/*
 * Wonders grid JS Library 
 * Copyright (c) 2003-2007 Wonders Information Co.,Ltd. All Rights Reserved.
 * Ext 2.0 including override method
 */

/*******************************************************************************
 * 第三方组件引入
 *******************************************************************************/

/**
 * @ignore
 */
Ext.grid.CheckColumn = function(config){
    Ext.apply(this, config);
    if(!this.id){
        this.id = Ext.id();
    }
    this.renderer = this.renderer.createDelegate(this);
};

/**
 * @ignore
 */
Ext.grid.CheckColumn.prototype ={
    init : function(grid){
        this.grid = grid;
        this.grid.on('render', function(){
            var view = this.grid.getView();
            view.mainBody.on('mousedown', this.onMouseDown, this);
        }, this);
    },

    onMouseDown : function(e, t){
        if(t.className && t.className.indexOf('x-grid3-cc-'+this.id) != -1){
            e.stopEvent();
            var index = this.grid.getView().findRowIndex(t);
            var record = this.grid.store.getAt(index);
            var type = record.fields.get(this.dataIndex).type;
            if (type == 'boolean') {
            	record.set(this.dataIndex, !record.data[this.dataIndex]);
            }
            else if (type == 'int') {
            	record.set(this.dataIndex, 1-record.data[this.dataIndex]);
            }
        }
    },

    renderer : function(v, p, record){
        p.css += ' x-grid3-check-col-td';
        return '<div class="x-grid3-check-col'+(v?'-on':'')+' x-grid3-cc-'+this.id+'">&#160;</div>';
    }
};

/**
 * @ignore
 */
Ext.grid.TreeCheckColumn = function(config){
    Ext.apply(this, config);
    if(!this.id){
        this.id = Ext.id();
    }
    this.renderer = this.renderer.createDelegate(this);
};

/**
 * @ignore
 */
Ext.grid.TreeCheckColumn.prototype ={
    init : function(grid){
        this.grid = grid;
        var view = this.grid.getView();
        if (view && view.mainBody) {
            view.mainBody.on('mousedown', this.onMouseDown, this);
        }
    },

    onMouseDown : function(e, t){
        if(t.className && t.className.indexOf('x-grid3-cc-'+this.id) != -1){
            e.stopEvent();
            var index = this.grid.getView().findRowIndex(t);
            var record = this.grid.store.getAt(index);
            var type = record.fields.get(this.dataIndex).type;
            if (type == 'boolean') {
            	record.set(this.dataIndex, !record.data[this.dataIndex]);
            }
            else if (type == 'int') {
            	record.set(this.dataIndex, 1-record.data[this.dataIndex]);
            }
        }
    },

    renderer : function(v, p, record){
        p.css += ' x-grid3-check-col-td';
        return '<div class="x-grid3-check-col'+(v?'-on':'')+' x-grid3-cc-'+this.id+'">&#160;</div>';
    }
};

/**
 * @ignore
 * 表格合计
 */
Wonders.grid.GridSummary = function(config) {
        Ext.apply(this, config);
};

Ext.extend(Wonders.grid.GridSummary, Ext.util.Observable, {

    init : function(grid) {
        this.grid = grid;
        this.cm = grid.getColumnModel();
        this.view = grid.getView();

        var v = this.view;

        // override GridView's onLayout() method
        v.onLayout = this.onLayout;

        v.afterMethod('render', this.refreshSummary, this);
        v.afterMethod('refresh', this.refreshSummary, this);
        v.afterMethod('syncScroll', this.syncSummaryScroll, this);
        v.afterMethod('onColumnWidthUpdated', this.doWidth, this);
        v.afterMethod('onAllColumnWidthsUpdated', this.doAllWidths, this);
        v.afterMethod('onColumnHiddenUpdated', this.doHidden, this);

        // update summary row on store's add/remove/clear/update events
        grid.store.on({
            add: this.refreshSummary,
            remove: this.refreshSummary,
            clear: this.refreshSummary,
            update: this.refreshSummary,
            scope: this
        });
        
        if(grid.rowSelectSummary==true){
	        grid.getSelectionModel().on({
	            rowselect : this.refreshSummary,
	            rowdeselect : this.refreshSummary,
	            scope: this
	        });
        }

        if (!this.rowTpl) {
        	// huyunming20160513,修改统计表格底部换行问题
        	/*
            this.rowTpl = new Ext.Template(
                '<div class="x-grid3-summary-row x-grid3-gridsummary-row-offset">',
                    '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                        '<tbody><tr><td class="x-grid3-col x-grid3-cell">',
                        	'<div class="x-grid3-cell-inner">', this.grid.summaryText, '</div>',
                        '</td></tr></tbody>',
                    '</table>',                
                    '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                        '<tbody><tr>{cells}</tr></tbody>',
                    '</table>',
                '</div>'
            );*/
        	if(!this.grid.subSummaryText){
        		this.rowTpl = new Ext.Template(
        	        '<div class="x-grid3-summary-row x-grid3-gridsummary-row-offset">',
        	            '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
        	                '<tbody><tr><td class="x-grid3-col x-grid3-cell">',
        	                	//'<div class="x-grid3-cell-inner">', this.grid.summaryText, '</div>',
        	                '</td></tr></tbody>',
        	            '</table>',                
        	            '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
        	                '<tbody><tr>{cells}</tr></tbody>',
        	            '</table>',
        	        '</div>'
        	    );
        	}else{
        		this.rowTpl = new Ext.Template(
        	        '<div class="x-grid3-summary-row x-grid3-gridsummary-row-offset">',
        	            '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
        	                '<tbody><tr><td class="x-grid3-col x-grid3-cell">',
        	                	'<div class="x-grid3-cell-inner">', this.grid.summaryText, '</div>',
        	                '</td></tr></tbody>',
        	            '</table>',                
        	            '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
        	                '<tbody><tr>{cells}</tr></tbody>',
        	            '</table>',
        	        '</div>'
        	    );
        	}
            //--
            this.rowTpl.disableFormats = true;
        }
        this.rowTpl.compile();

        if (!this.cellTpl) {
            this.cellTpl = new Ext.Template(
                '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
                    '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
                "</td>"
            );
            this.cellTpl.disableFormats = true;
        }
        this.cellTpl.compile();
    },

    calculate : function(rs, cm) {
        var data = {}, cfg = cm.config;
        for (var i = 0, len = cfg.length; i < len; i++) { // loop through all columns in ColumnModel
            var cf = cfg[i]; // get column's configuration
            
            if (cf.summaryType) {            

                cname = cf.dataIndex; // get column dataIndex
	            // initialise grid summary row data for
	            // the current column being worked on
	            data[cname] = 0;

	            var values = new Array();
                for (var j = 0, jlen = rs.length; j < jlen; j++) {
                    var r = rs[j]; // get a single Record
                    var v = isNaN(r.get(cname)) ? '' : parseFloat(r.get(cname));
                    // data[cname] = Wonders.grid.GridSummary.Calculations[cf.summaryType](v, r, cname, data, j);
                    values[values.length] = Ext.num(v, 0);
                }
                if (values.length > 0) {
                	data[cname] = Wonders.grid.GridSummary.Calculations[cf.summaryType](values, rs, cname);
                }
                
                if (cf.summaryType != "count" && data[cname]) {
                	data[cname] = data[cname].toFixed(cf.summaryDecimalPrecision);
                }
            }
        }
        return data;
    },

    onLayout : function(vw, vh) {
        if (Ext.type(vh) != 'number') { // handles grid's height:'auto' config
            return;
        }
        // note: this method is scoped to the GridView
        if (!this.grid.getGridEl().hasClass('x-grid-hide-gridsummary')) {
            // readjust gridview's height only if grid summary row is visible
            this.scroller.setHeight(vh - this.summary.getHeight());
        }
    },

    syncSummaryScroll : function() {
        var mb = this.view.scroller.dom;

        this.view.summaryWrap.dom.scrollLeft = mb.scrollLeft;
        this.view.summaryWrap.dom.scrollLeft = mb.scrollLeft; // second time for IE (1/2 time first fails, other browsers ignore)
    },

    doWidth : function(col, w, tw) {
        var s = this.view.summary.dom;

        s.childNodes[1].style.width = tw;
        s.childNodes[1].rows[0].childNodes[col].style.width = w;
    },

    doAllWidths : function(ws, tw) {
        var s = this.view.summary.dom, wlen = ws.length;

        s.childNodes[1].style.width = tw;

        var cells = s.childNodes[1].rows[0].childNodes;

        for (var j = 0; j < wlen; j++) {
            cells[j].style.width = ws[j];
        }
    },

    doHidden : function(col, hidden, tw) {
        var s = this.view.summary.dom,
            display = hidden ? 'none' : '';

        s.childNodes[1].style.width = tw;
        s.childNodes[1].rows[0].childNodes[col].style.display = display;
    },

    renderSummary : function(o, cs, cm) {
        cs = cs || this.view.getColumnData();
        var cfg = cm.config,
            buf = [],
            last = cs.length - 1;

        for (var i = 0, len = cs.length; i < len; i++) {
            var c = cs[i], cf = cfg[i], p = {};

            p.id = c.id;
            p.style = c.style;
            p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');

            if (cf.summaryType && (o.data[c.name] != undefined)) {
                p.value = (cf.summaryRenderer || c.renderer)(o.data[c.name], p, o);
            } else {
                p.value = '';
            }
            if (p.value === undefined || p.value === "") {
                p.value = "&#160;";
            }
            
            // huyunming20160513 底部添加统计文本
            if(p.id=="rowNumber"){
            	p.value=this.grid.summaryText;
            }
            //--
            buf[buf.length] = this.cellTpl.apply(p);
        }

        return this.rowTpl.apply({
            tstyle: 'width:' + this.view.getTotalWidth() + ';',
            cells: buf.join('')
        });
    },

    refreshSummary : function() {
        var g = this.grid, ds = g.store,
            cs = this.view.getColumnData(),
            cm = this.cm,
            rs = ds.getRange();
            
        if(g.rowSelectSummary==true){
					if(g.getSelectionModel().getSelections().length>0){
							rs = g.getSelectionModel().getSelections();
					}
					else{
						rs = [];
					}
				}
        var data = [];
				if (ds.remoteSummary && ds.getSummaryData()) {
					data = ds.getSummaryData();
        }
        else {
					data = this.calculate(rs, cm);
        }
        var buf = this.renderSummary({data: data}, cs, cm);
        
        if (!this.view.summaryWrap) {
            this.view.summaryWrap = Ext.DomHelper.insertAfter(this.view.scroller, {
                tag: 'div',
                cls: 'x-grid3-gridsummary-row-inner'
            }, true);
        }
        this.view.summary = this.view.summaryWrap.update(buf).first();
    },

    toggleSummary : function(visible) { // true to display summary row
        var el = this.grid.getGridEl();

        if (el) {
            if (visible === undefined) {
                visible = el.hasClass('x-grid-hide-gridsummary');
            }
            el[visible ? 'removeClass' : 'addClass']('x-grid-hide-gridsummary');

            this.view.layout(); // readjust gridview height
        }
    },

    getSummaryNode : function() {
        return this.view.summary;
    }
});
Ext.reg('gridsummary', Wonders.grid.GridSummary);

/*
 * all Calculation methods are called on each Record in the Store
 * with the following 5 parameters:
 *
 * v - cell value
 * record - reference to the current Record
 * colName - column name (i.e. the ColumnModel's dataIndex)
 * data - the cumulative data for the current column + summaryType up to the current Record
 * rowIdx - current row index
 */

Wonders.grid.GridSummary.Calculations = {
	/**
	 * @ignore
	 */
	floatAdd: function(arg1,arg2) {
		var r1,r2,m;
	    try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
	    try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
	    if(r1>=r2) {
	    	return ((Number)(arg1.toString().replace(".","")) + (Number)(arg2.toString().replace(".",""))*Math.pow(10,r1-r2)) / Math.pow(10,r1);
	    }
	    else {
	    	return ((Number)(arg1.toString().replace(".",""))*Math.pow(10,r2-r1) + (Number)(arg2.toString().replace(".",""))) / Math.pow(10,r2);
	    }
	}, 
	
	/**
	 * @ignore
	 */
	/*
    sum : function(v, record, colName, data, rowIdx) {
        //return data[colName] + Ext.num(v, 0);
        var arg1 = data[colName];
       	var arg2 = Ext.num(v, 0);
        return this.floatAdd(arg1,arg2);
    },
    */
	sum : function(values, records, colName) {
		var result = 0;
		for (var i=0; i<values.length; i++) {
			result = this.floatAdd(result, values[i]);
		}
		return result;
	},

	/**
	 * @ignore
	 */
	/*
    count : function(v, record, colName, data, rowIdx) {
        return rowIdx + 1;
    },
    */
	count : function(values, records, colName) {
		return values.length;
	},

	/**
	 * @ignore
	 */
	/*
    max : function(v, record, colName, data, rowIdx) {
        return Math.max(Ext.num(v, 0), data[colName]);
    },
    */
	max : function(values, records, colName) {
		return Math.max.apply(Math, values);
	},

	/**
	 * @ignore
	 */
	/*
    min : function(v, record, colName, data, rowIdx) {
        return Math.min(Ext.num(v, 0), data[colName]);
    },
    */
	min : function(values, records, colName) {
		return Math.min.apply(Math, values);
	},

	/**
	 * @ignore
	 */
	/*
    average : function(v, record, colName, data, rowIdx) {
        var t = data[colName] + Ext.num(v, 0), count = record.store.getCount();
        return rowIdx == count - 1 ? (t / count) : t;
    }
    */
	average : function(values, records, colName) {
    	return this.sum(values) / values.length;
    }
};

/**
 * @ignore
 * 表格分组合计
 */
Wonders.grid.GroupSummary = function(config){
    Ext.apply(this, config);
};

Ext.extend(Wonders.grid.GroupSummary, Ext.util.Observable, {

    init : function(grid){
        this.grid = grid;
        this.cm = grid.getColumnModel();
        this.view = grid.getView();

        var v = this.view;
        v.doGroupEnd = this.doGroupEnd.createDelegate(this);

        v.afterMethod('onColumnWidthUpdated', this.doWidth, this);
        v.afterMethod('onAllColumnWidthsUpdated', this.doAllWidths, this);
        v.afterMethod('onColumnHiddenUpdated', this.doHidden, this);
        v.afterMethod('onUpdate', this.doUpdate, this);
        v.afterMethod('onRemove', this.doRemove, this);

        if(!this.rowTpl){
            this.rowTpl = new Ext.Template(
                '<div class="x-grid3-summary-row" style="{tstyle}">',
                    '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                        '<tbody><tr><td class="x-grid3-col x-grid3-cell">',
                        	'<div class="x-grid3-cell-inner">', this.grid.summaryText, '</div>',
                        '</td></tr></tbody>',
                    '</table>',  
                '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                    '<tbody><tr>{cells}</tr></tbody>',
                '</table></div>'
            );
            this.rowTpl.disableFormats = true;
        }
        this.rowTpl.compile();
        
        if(!this.subRowTpl){
        	// huyunming20160513 统计表格行合并
        	/*
            this.subRowTpl = new Ext.Template(
                '<div class="x-grid3-summary-row" style="{tstyle}">',
                    '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                        '<tbody><tr><td class="x-grid3-col x-grid3-cell">',
                        	'<div class="x-grid3-cell-inner">', this.grid.subSummaryText, '</div>',
                        '</td></tr></tbody>',
                    '</table>',  
                '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                    '<tbody><tr>{cells}</tr></tbody>',
                '</table></div>'
            );*/
        	this.subRowTpl = new Ext.Template(
                '<div class="x-grid3-summary-row" style="{tstyle}">',
                    '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                        '<tbody><tr><td class="x-grid3-col x-grid3-cell">',
                        	'<div class="x-grid3-cell-inner">', this.grid.subSummaryText, '</div>',
                        '</td></tr></tbody>',
                    '</table>',  
                '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                    '<tbody><tr>{cells}</tr></tbody>',
                '</table></div>'
            );
            // --
            this.subRowTpl.disableFormats = true;
        }
        this.subRowTpl.compile();

        if(!this.cellTpl){
            this.cellTpl = new Ext.Template(
                '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
                '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on">{value}</div>',
                "</td>"
            );
            this.cellTpl.disableFormats = true;
        }
        this.cellTpl.compile();
    },

    toggleSummaries : function(visible){
        var el = this.grid.getGridEl();
        if(el){
            if(visible === undefined){
                visible = el.hasClass('x-grid-hide-summary');
            }
            el[visible ? 'removeClass' : 'addClass']('x-grid-hide-summary');
        }
    },

    renderSummary : function(o, cs, sub){
        cs = cs || this.view.getColumnData();
        var cfg = this.cm.config;

        var buf = [], c, p = {}, cf, last = cs.length-1;
        for(var i = 0, len = cs.length; i < len; i++){
            c = cs[i];
            cf = cfg[i];
            p.id = c.id;
            p.style = c.style;
            p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
            if(cf.summaryType && (o.data[c.name] != undefined)){
                p.value = (cf.summaryRenderer || c.renderer)(o.data[c.name], p, o);
            }else{
                p.value = '';
            }
            if(p.value == undefined || p.value === "") p.value = "&#160;";
            buf[buf.length] = this.cellTpl.apply(p);
        }

		if(sub) {
	        return this.subRowTpl.apply({
	            tstyle: 'width:'+this.view.getTotalWidth()+';',
	            cells: buf.join('')
	        });
		}
		else {
	        return this.rowTpl.apply({
	            tstyle: 'width:'+this.view.getTotalWidth()+';',
	            cells: buf.join('')
	        });
	    }
    },

    calculate : function(rs, cs){
        var data = {}, r, c, cfg = this.cm.config, cf;
        for(var i = 0, len = cs.length; i < len; i++){
            c = cs[i];
            cf = cfg[i];
            for(var j = 0, jlen = rs.length; j < jlen; j++){
            	r = rs[j];
                if(cf.summaryType){
                	var v = isNaN(data[c.name]) ? '' : parseFloat(data[c.name]);
                    data[c.name] = Wonders.grid.GroupSummary.Calculations[cf.summaryType](v || 0, r, c.name, data);
                }
            }
            if (cf.summaryType && cf.summaryType != "count" && data[c.name]) {
				data[c.name] = data[c.name].toFixed(cf.summaryDecimalPrecision);
            }
        }
        return data;
    },

    doGroupEnd : function(buf, g, cs, ds, colCount){
        var data = this.calculate(g.rs, cs);
        buf.push('</div>', this.renderSummary({data: data}, cs, true), '</div>');
    },

    doWidth : function(col, w, tw){
        var gs = this.view.getGroups(), s;
        for(var i = 0, len = gs.length; i < len; i++){
            s = gs[i].childNodes[2];
            if(s != undefined) {
	            s.style.width = tw;
	            s.childNodes[1].style.width = tw;
	            s.childNodes[1].rows[0].childNodes[col].style.width = w;
	        }
        }
    },

    doAllWidths : function(ws, tw){
        var gs = this.view.getGroups(), s, cells, wlen = ws.length;
        for(var i = 0, len = gs.length; i < len; i++){
            s = gs[i].childNodes[2];
	            if(s != undefined) {
	            s.style.width = tw;
	            s.childNodes[1].style.width = tw;
	            cells = s.childNodes[1].rows[0].childNodes;
	            for(var j = 0; j < wlen; j++){
	                cells[j].style.width = ws[j];
	            }
	        }
        }
    },

    doHidden : function(col, hidden, tw){
        var gs = this.view.getGroups(), s, display = hidden ? 'none' : '';
        for(var i = 0, len = gs.length; i < len; i++){
            s = gs[i].childNodes[2];
            if(s != undefined) {
	            s.style.width = tw;
	            s.childNodes[1].style.width = tw;
	            s.childNodes[1].rows[0].childNodes[col].style.display = display;
	        }
        }
    },

    // Note: requires that all (or the first) record in the 
    // group share the same group value. Returns false if the group
    // could not be found.
    refreshSummary : function(groupValue){
        return this.refreshSummaryById(this.view.getGroupId(groupValue));
    },

    getSummaryNode : function(gid){
        var g = Ext.fly(gid, '_gsummary');
        if(g){
            return g.down('.x-grid3-summary-row', true);
        }
        return null;
    },

    refreshSummaryById : function(gid){
        var g = document.getElementById(gid);
        if(!g){
            return false;
        }
        var rs = [];
        this.grid.store.each(function(r){
            if(r._groupId == gid){
                rs[rs.length] = r;
            }
        });
        var cs = this.view.getColumnData();
        var data = this.calculate(rs, cs);
        var markup = this.renderSummary({data: data}, cs);

        var existing = this.getSummaryNode(gid);
        if(existing){
            g.removeChild(existing);
        }
        Ext.DomHelper.append(g, markup);
        return true;
    },

    doUpdate : function(ds, record){
        this.refreshSummaryById(record._groupId);
    },

    doRemove : function(ds, record, index, isUpdate){
        if(!isUpdate){
            this.refreshSummaryById(record._groupId);
        }
    },

    showSummaryMsg : function(groupValue, msg){
        var gid = this.view.getGroupId(groupValue);
        var node = this.getSummaryNode(gid);
        if(node){
            node.innerHTML = '<div class="x-grid3-summary-msg">' + msg + '</div>';
        }
    }
});

/**
 * @ignore
 */
Wonders.grid.GroupSummary.Calculations = {
	
		/**
		 * @ignore
		 */
		floatAdd: function(arg1,arg2) {
			var r1,r2,m;
		    try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
		    try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
		    if(r1>=r2) {
		    	return ((Number)(arg1.toString().replace(".","")) + (Number)(arg2.toString().replace(".",""))*Math.pow(10,r1-r2)) / Math.pow(10,r1);
		    }
		    else {
		    	return ((Number)(arg1.toString().replace(".",""))*Math.pow(10,r2-r1) + (Number)(arg2.toString().replace(".",""))) / Math.pow(10,r2);
		    }
		}, 
		
    'sum' : function(v, record, field){
        //return v + (record.data[field]||0);
    	  var arg1 = Ext.num(record.data[field], 0);
       	var arg2 = Ext.num(v, 0);
        return this.floatAdd(arg1,arg2);
    },

    'count' : function(v, record, field, data){
        return data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1);
    },

    'max' : function(v, record, field, data){
        var v = record.data[field];
        var max = data[field+'max'] === undefined ? (data[field+'max'] = v) : data[field+'max'];
        return v > max ? (data[field+'max'] = v) : max;
    },

    'min' : function(v, record, field, data){
        var v = record.data[field];
        var min = data[field+'min'] === undefined ? (data[field+'min'] = v) : data[field+'min'];
        return v < min ? (data[field+'min'] = v) : min;
    },

    'average' : function(v, record, field, data){
        var c = data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1);
        var t = (data[field+'total'] = ((data[field+'total']||0) + (record.data[field]||0)));
        return t === 0 ? 0 : t / c;
    }
}

Wonders.grid.HybridSummary = Ext.extend(Wonders.grid.GroupSummary, {
    calculate : function(rs, cs){
        var gcol = this.view.getGroupField();
        var gvalue = rs[0].data[gcol];
        var gdata = this.getSummaryData(gvalue);
        return gdata || Wonders.grid.HybridSummary.superclass.calculate.call(this, rs, cs);
    },

    updateSummaryData : function(groupValue, data, skipRefresh){
        var json = this.grid.store.reader.jsonData;
        if(!json.summaryData){
            json.summaryData = {};
        }
        json.summaryData[groupValue] = data;
        if(!skipRefresh){
            this.refreshSummary(groupValue);
        }
    },

    getSummaryData : function(groupValue){
        var json = this.grid.store.reader.jsonData;
        if(json && json.summaryData){
            return json.summaryData[groupValue];
        }
        return null;
    }
});

/*******************************************************************************
 * 表格组件方法重写
 *******************************************************************************/

/**
 * 表格分组视图
 */
Ext.apply(Ext.grid.GroupingView.prototype, {

	 	// private
    doRender : function(cs, rs, ds, startRow, colCount, stripe){
        if(rs.length < 1){
            return '';
        }
        var groupField = this.getGroupField();
        var colIndex = this.cm.findColumnIndex(groupField);

        this.enableGrouping = !!groupField;

        if(!this.enableGrouping || this.isUpdating){
            return Ext.grid.GroupingView.superclass.doRender.apply(
                    this, arguments);
        }
        var gstyle = 'width:'+this.getTotalWidth()+';';

        var gidPrefix = this.grid.getGridEl().id;
        var cfg = this.cm.config[colIndex];
        var groupRenderer = cfg.groupRenderer || cfg.renderer;
        var prefix = this.showGroupName ?
                     (cfg.groupName || cfg.header)+': ' : '';

        var groups = [], curGroup, i, len, gid;
        for(i = 0, len = rs.length; i < len; i++){
            var rowIndex = startRow + i;
            
            /***增加分组显示的列对应于字典项的渲染***/
            var r = rs[i];
            var gvalue = r.data[groupField];
            for (var j = 0; j < colCount; j++) {
							c = cs[j];
							if(c.dicBind){
								if(c.name == groupField){
									gvalue = Wonders.grid.transformDicData(gvalue, c.dicBind);
								}
							}
            }
            var g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
            /******/
            
            if(!curGroup || curGroup.group != g){
                gid = gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(g);
               	// if state is defined use it, however state is in terms of expanded
								// so negate it, otherwise use the default.
								var isCollapsed  = typeof this.state[gid] !== 'undefined' ? !this.state[gid] : this.startCollapsed;
								var gcls = isCollapsed ? 'x-grid-group-collapsed' : '';	
                curGroup = {
                    group: g,
                    gvalue: gvalue,
                    text: prefix + g,
                    groupId: gid,
                    startRow: rowIndex,
                    rs: [r],
                    cls: gcls,
                    style: gstyle
                };
                groups.push(curGroup);
            }else{
                curGroup.rs.push(r);
            }
            r._groupId = gid;
        }

        var buf = [];
        for(i = 0, len = groups.length; i < len; i++){
            var g = groups[i];
            this.doGroupStart(buf, g, cs, ds, colCount);
            buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
                    this, cs, g.rs, ds, g.startRow, colCount, stripe);

            this.doGroupEnd(buf, g, cs, ds, colCount);
        }
        return buf.join('');
    }
})

/**
 * @ignore
 * 表格分组2视图
 */
Ext.grid.GroupingView2 = Ext.extend(Ext.grid.GroupingView, {
	// updated
	groupHeaderClass : '.x-grid-customer-group-hd',
	// added
	additionalGroupFields : new Array,
	// added
	untetheredFields : new Array,

	// private
	interceptMouse : function(e) {
		// perv: '.x-grid-group-hd'
		var hd = e.getTarget(this.groupHeaderClass, this.mainBody);
		if (hd) {
			e.stopEvent();
			this.toggleGroup(hd.parentNode);
		}
	},

	// private
	renderRows : function() {
		var groupField = this.getGroupField();
		var eg = !!groupField;
		// if they turned off grouping and the last grouped field is hidden
		if (this.hideGroupedColumn) {
			var colIndex = this.cm.findColumnIndex(groupField);
			if (!eg && this.lastGroupField !== undefined) {
				this.mainBody.update('');
				this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField),
						false);
				delete this.lastGroupField;
			} else if (eg && this.lastGroupField === undefined) {
				// prev normal do this
				this.lastGroupField = groupField;
				// prev :
				// this.cm.setHidden(colIndex, true);
				// update :
				var cm = this.grid.colModel;
				cm.moveColumn(colIndex, 0);
			} else if (eg && this.lastGroupField !== undefined
					&& groupField !== this.lastGroupField) {
				this.mainBody.update('');
				var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
				this.cm.setHidden(oldIndex, false);
				this.lastGroupField = groupField;
				this.cm.setHidden(colIndex, true);
			}
		}
		return Ext.grid.GroupingView.superclass.renderRows.apply(this,
				arguments);
	},

	// private inherited from gridView
	getColumnData : function() {
		// build a map for all the columns
		var cs = [], cm = this.cm, colCount = cm.getColumnCount();
		for (var i = 0; i < colCount; i++) {
			var name = cm.getDataIndex(i);
			cs[i] = {
				name : (typeof name == 'undefined'
						? this.ds.fields.get(i).name
						: name),
				renderer : cm.getRenderer(i),
				id : cm.getColumnId(i),
				style : this.getColumnStyle(i)
				// added by chenweijie
				,
				groupHeaderRenderer : cm.config[i].groupHeaderRenderer
			};
		}
		return cs;
	},

	// private inherited from gridView
	doRender : function(cs, rs, ds, startRow, colCount, stripe) {
		if (rs.length < 1) {
			return '';
		}
		var groupField = this.getGroupField();

		var colIndex = this.cm.findColumnIndex(groupField);

		this.enableGrouping = !!groupField;

		// added by cwj: don't group or loading data
		if (!this.enableGrouping || this.isUpdating) {
			return Ext.grid.GroupingView.superclass.doRender.apply(this,
					arguments);
		}
		var gstyle = 'width:' + this.getTotalWidth() + ';';

		var gidPrefix = this.grid.getGridEl().id;
		var cfg = this.cm.config[colIndex];
		var groupRenderer = cfg.groupRenderer || cfg.renderer;
		var cls = this.startCollapsed ? 'x-grid-group-collapsed' : '';
		var prefix = this.showGroupName
				? (cfg.groupName || cfg.header) + ': '
				: '';
		// init groups obj
		var groups = [], curGroup, i, len, gid;
		for (i = 0, len = rs.length; i < len; i++) {
			var rowIndex = startRow + i;
			var r = rs[i], gvalue = r.data[groupField], g = this.getGroup(
					gvalue, r, groupRenderer, rowIndex, colIndex, ds);
			if (!curGroup || curGroup.group != g) {
				gid = gidPrefix + '-gp-' + groupField + '-' + g;
				var gcls = cls ? cls : (this.state[gid] === false
						? 'x-grid-group-collapsed'
						: '');
				curGroup = {
					group : g,
					gvalue : gvalue,
					text : prefix + g,
					groupId : gid,
					startRow : rowIndex,
					rs : [r],
					cls : gcls,
					style : gstyle
				};
				groups.push(curGroup);
			} else {
				curGroup.rs.push(r);
			}
			r._groupId = gid;
		}

		var buf = [];
		for (i = 0, len = groups.length; i < len; i++) {
			var g = groups[i];
			// prev :
			// this.doGroupStart(buf, g, cs, ds, colCount);
			this.doCustomerGroupStart(buf, g, cs, ds, colCount, stripe);
			// prev :
			// buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
			// this, cs, g.rs, ds, g.startRow, colCount, stripe);
			buf[buf.length] = this.doCustomerRenderNormal(cs, g.rs, ds,
					g.startRow, colCount, stripe, g.style);
			// prev :
			// this.doGroupEnd(buf, g, cs, ds, colCount);
			this.doCustomerGroupEnd(buf, g, cs, ds, colCount);
		}
		return buf.join('');
	},

	// private
	initTemplates : function() {
		Ext.grid.GroupingView.superclass.initTemplates.call(this);
		if (!this.templates.groupHeaderRow) {
			this.templates.groupHeaderRowTemplate = new Ext.Template(
					'<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
					'<tbody><tr>{cells}</tr>',
					(this.enableRowBody
							? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>'
							: ''), '</tbody></table></div>');
		}
		this.templates.groupHeaderRowTemplate.disableFormats = true;
		this.templates.groupHeaderRowTemplate.compile();

		if (!this.templates.groupHeaderCellTemplate) {
			this.templates.groupHeaderCellTemplate = new Ext.Template(
					'<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" class="x-grid3-td-{id}" style="{style}" tabIndex="0" {cellAttr}>',
					'<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
					"</td>");
		}
		this.templates.groupHeaderCellTemplate.disableFormats = true;
		this.templates.groupHeaderCellTemplate.compile();

		this.state = {};

		var sm = this.grid.getSelectionModel();
		sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
				this.onBeforeRowSelect, this);

		if (!this.startGroup) {
			// prev :
			/**
			 * @ignore
			 * this.startGroup = new Ext.XTemplate( '<div id="{groupId}"
			 * class="x-grid-group {cls}">', '<div id="{groupId}-hd"
			 * class="x-grid-group-hd" style="{style}"><div>',
			 * this.groupTextTpl ,'</div></div>', '<div id="{groupId}-bd"
			 * class="x-grid-group-body">' );
			 */
			this.startGroup = new Ext.XTemplate(
					'<div id="{groupId}" class="x-grid-group {cls}">',
					'<div id="{groupId}-hd" class="x-grid-customer-group-hd" style="{style}">{grouprow}</div>',
					'<div id="{groupId}-bd" class="x-grid-group-body">');
		}
		this.startGroup.compile();
		this.endGroup = '</div></div>';
	},

	// private added by cwj
	getHeaderRows : function() {
		if (!this.enableGrouping) {
			return Ext.grid.GroupingView.superclass.getRows.call(this);
		}
		var r = [];
		var g, gs = this.getGroups();
		for (var i = 0, len = gs.length; i < len; i++) {
			g = gs[i].childNodes[0].childNodes;
			for (var j = 0, jlen = g.length; j < jlen; j++) {
				r[r.length] = g[j];
			}
		}
		return r;
	},

	// private
	updateAllColumnWidths : function() {
		var tw = this.getTotalWidth();
		var clen = this.cm.getColumnCount();
		var ws = [];
		for (var i = 0; i < clen; i++) {
			ws[i] = this.getColumnWidth(i);
		}

		this.innerHd.firstChild.firstChild.style.width = tw;

		for (var i = 0; i < clen; i++) {
			var hd = this.getHeaderCell(i);
			hd.style.width = ws[i];
		}

		var ns = this.getRows();
		// row template data
		for (var i = 0, len = ns.length; i < len; i++) {
			ns[i].style.width = tw;
			ns[i].firstChild.style.width = tw;
			var row = ns[i].firstChild.rows[0];
			for (var j = 0; j < clen; j++) {
				row.childNodes[j].style.width = ws[j];
			}
		}

		// updated by cwj
		var groupHeaders = this.getHeaderRows();
		for (var i = 0; i < groupHeaders.length; i++) {
			if (groupHeaders[i]) {
				groupHeaders[i].style.width = tw;
				groupHeaders[i].firstChild.style.width = tw;
				var row = groupHeaders[i].firstChild.rows[0];
				for (var j = 0; j < clen; j++) {
					row.childNodes[j].style.width = ws[j];
				}
			}
		}
		this.onAllColumnWidthsUpdated(ws, tw);
	},

	// private
	updateColumnWidth : function(col, width) {
		var w = this.getColumnWidth(col);
		var tw = this.getTotalWidth();

		this.innerHd.firstChild.firstChild.style.width = tw;
		var hd = this.getHeaderCell(col);
		hd.style.width = w;

		var ns = this.getRows();
		for (var i = 0, len = ns.length; i < len; i++) {
			ns[i].style.width = tw;
			ns[i].firstChild.style.width = tw;
			ns[i].firstChild.rows[0].childNodes[col].style.width = w;
		}

		// updated by cwj
		var groupHeaders = this.getHeaderRows();
		for (var i = 0; i < groupHeaders.length; i++) {
			if (groupHeaders[i]) {
				groupHeaders[i].style.width = tw;
				groupHeaders[i].firstChild.style.width = tw;
				groupHeaders[i].firstChild.rows[0].childNodes[col].style.width = w;
			}
		}

		this.onColumnWidthUpdated(col, w, tw);
	},

	// private
	updateColumnHidden : function(col, hidden) {
		var tw = this.getTotalWidth();

		this.innerHd.firstChild.firstChild.style.width = tw;

		var display = hidden ? 'none' : '';

		var hd = this.getHeaderCell(col);
		hd.style.display = display;

		var ns = this.getRows();
		for (var i = 0, len = ns.length; i < len; i++) {
			ns[i].style.width = tw;
			ns[i].firstChild.style.width = tw;
			ns[i].firstChild.rows[0].childNodes[col].style.display = display;
		}

		// updated by cwj
		var groupHeaders = this.getHeaderRows();
		for (var i = 0; i < groupHeaders.length; i++) {
			if (groupHeaders[i]) {
				groupHeaders[i].style.width = tw;
				groupHeaders[i].firstChild.style.width = tw;
				groupHeaders[i].firstChild.rows[0].childNodes[col].style.display = display;
			}
		}

		this.onColumnHiddenUpdated(col, hidden, tw);

		delete this.lastViewWidth; // force recalc
		this.layout();
	},

	// private
	doCustomerGroupStart : function(buf, g, cs, ds, colCount, stripe) {
		// prev:
		// buf[buf.length] = this.startGroup.apply(g);
		// display other specified column Values
		var groupheaderRow = new Array();
		groupheaderRow.push(g.rs[0]);
		g.grouprow = this.doCustomerRenderHearderRow(cs, groupheaderRow, ds,
				g.startRow, colCount, stripe, g.style);// g.rs
		var result = this.startGroup.apply(g);
		buf[buf.length] = result;
	},

	// private
	doCustomerGroupEnd : function(buf, g, cs, ds, colCount) {
		buf[buf.length] = this.endGroup;
	},

	doCustomerRenderHearderRow : function(cs, rs, ds, startRow, colCount,
			stripe, gstyle) {
		var ts = this.templates, ct = ts.groupHeaderCellTemplate, rt = ts.groupHeaderRowTemplate, last = colCount
				- 1;// ts.cell ts.row

		var tstyle = gstyle;// 'width:'+this.getTotalWidth()+';';
		// alert('Group header Table width: ' + tstyle);
		// update
		var groupField = this.getGroupField();

		// buffers
		var buf = [], cb, c, p = {}, rp = {
			tstyle : tstyle
		}, r;
		for (var j = 0, len = rs.length; j < len; j++) {
			r = rs[j];
			cb = [];
			var rowIndex = (j + startRow);
			for (var i = 0; i < colCount; i++) {
				c = cs[i];
				p.id = c.id;
				// update by cwj : denotation the default cell css.
				p.css = i == 0 ? 'x-grid3-cell-firstXX ' : (i == last
						? 'x-grid3-cell-last '
						: '');

				// update by cwj : add folder icon css
				if (groupField == c.name) {
					p.css += 'x-grid3-customer-cell-folder ';
				}

				p.attr = p.cellAttr = "";
				if (c.groupHeaderRenderer) {
					p.value = c.groupHeaderRenderer(r.data[c.name], p, r,
							rowIndex, i, ds);
				} else {
					p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
				}
				p.style = c.style;
				if (p.value == undefined || p.value === "")
					p.value = "&#160;";

				// update by cwj : don't display the unspecified group field in
				// header region
				if (this.untetheredFields.indexOf(c.name) == -1
						&& groupField != c.name
						&& this.additionalGroupFields.indexOf(c.name) == -1) {
					p.value = "";
				}

				if (r.dirty && typeof r.modified[c.name] !== 'undefined') {
					p.css += ' x-grid3-dirty-cell';
				}
				cb[cb.length] = ct.apply(p);
			}
			var alt = [];
			if (stripe && ((rowIndex + 1) % 2 == 0)) {
				alt[0] = "x-grid3-row-alt";
			}
			if (r.dirty) {
				alt[1] = " x-grid3-dirty-row";
			}
			rp.cols = colCount;
			if (this.getRowClass) {
				alt[2] = this.getRowClass(r, rowIndex, rp, ds);
			}
			rp.alt = alt.join(" ");
			rp.cells = cb.join("");
			buf[buf.length] = rt.apply(rp);
		}
		return buf.join("");
	},

	// private copy doRender api from gridview
	doCustomerRenderNormal : function(cs, rs, ds, startRow, colCount, stripe,
			gstyle) {
		var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount - 1;
		var tstyle = gstyle;// 'width:'+this.getTotalWidth()+';';

		// update
		var groupField = this.getGroupField();

		// buffers
		var buf = [], cb, c, p = {}, rp = {
			tstyle : tstyle
		}, r;
		for (var j = 0, len = rs.length; j < len; j++) {
			r = rs[j];
			cb = [];
			var rowIndex = (j + startRow);
			for (var i = 0; i < colCount; i++) {
				c = cs[i];
				p.id = c.id;
				p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last
						? 'x-grid3-cell-last '
						: '');
				p.attr = p.cellAttr = "";
				p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
				p.style = c.style;

				if (p.value == undefined || p.value === "")
					p.value = "&#160;";

				// update by cwj : don't display the group field in normal
				// region
				if (this.untetheredFields.indexOf(c.name) == -1
						&& groupField == c.name) {
					p.value = "";
				}

				// update by cwj : don't display the group field in normal
				// region
				if (groupField != c.name
						&& this.untetheredFields.indexOf(c.name) == -1
						&& this.additionalGroupFields.indexOf(c.name) > -1) {
					p.value = "";
				}

				if (r.dirty && typeof r.modified[c.name] !== 'undefined') {
					p.css += ' x-grid3-dirty-cell';
				}
				cb[cb.length] = ct.apply(p);
			}
			var alt = [];
			if (stripe && ((rowIndex + 1) % 2 == 0)) {
				alt[0] = "x-grid3-row-alt";
			}
			if (r.dirty) {
				alt[1] = " x-grid3-dirty-row";
			}
			rp.cols = colCount;
			if (this.getRowClass) {
				alt[2] = this.getRowClass(r, rowIndex, rp, ds);
			}
			rp.alt = alt.join(" ");
			rp.cells = cb.join("");
			buf[buf.length] = rt.apply(rp);
		}
		return buf.join("");
	}
});

// private cwj: unknown property
Ext.grid.GroupingView2.GROUP_ID = 1001;


/**
 * @ignore
 * Ext.PagingToolbar Override class definitions
 */
Ext.apply(Ext.PagingToolbar.prototype, {
	
	setPageSizeBefore : "\u6bcf\u9875\u663e\u793a",
	  
	setPageSizeAfter : "\u6761\u8bb0\u5f55",
		
		// private
    onRender : function(ct, position){
        Ext.PagingToolbar.superclass.onRender.call(this, ct, position);
        this.first = this.addButton({
            tooltip: this.firstText,
            iconCls: "x-tbar-page-first",
            disabled: true,
            handler: this.onClick.createDelegate(this, ["first"])
        });
        this.prev = this.addButton({
            tooltip: this.prevText,
            iconCls: "x-tbar-page-prev",
            disabled: true,
            handler: this.onClick.createDelegate(this, ["prev"])
        });
        this.addSeparator();
        this.add(this.beforePageText);
        this.field = Ext.get(this.addDom({
           tag: "input",
           type: "text",
           size: "3",
           value: "1",
           cls: "x-tbar-page-number"
        }).el);
        this.field.on("keydown", this.onPagingKeydown, this);
        this.field.on("focus", function(){this.dom.select();});
        this.afterTextEl = this.addText(String.format(this.afterPageText, 1));
        this.field.setHeight(18);
        this.addSeparator();
        this.next = this.addButton({
            tooltip: this.nextText,
            iconCls: "x-tbar-page-next",
            disabled: true,
            handler: this.onClick.createDelegate(this, ["next"])
        });
        this.last = this.addButton({
            tooltip: this.lastText,
            iconCls: "x-tbar-page-last",
            disabled: true,
            handler: this.onClick.createDelegate(this, ["last"])
        });
        this.addSeparator();
        this.loading = this.addButton({
            tooltip: this.refreshText,
            iconCls: "x-tbar-loading",
            handler: this.onClick.createDelegate(this, ["refresh"])
        });

        if(this.displayInfo){
            this.displayEl = Ext.fly(this.el.dom).createChild({cls:'x-paging-info'});
        }
        if(this.dsLoaded){
            this.onLoad.apply(this, this.dsLoaded);
        }
            
        this.add(this.setPageSizeBefore);
				this.fieldSetPage = Ext.get(this.addDom({
						tag : "input",
						type : "text",
						size : "10",
						value : this.pageSize,
						cls : "x-tbar-page-number"
				}).el);
				this.fieldSetPage.on("keydown", this.onSetPageSize, this); 
				this.fieldSetPage.setHeight(18); 
				this.add(this.setPageSizeAfter);
    },
    
    onSetPageSize : function(e) {
				var k = e.getKey(), d = this.getPageData(), pageNum;
				if (k == e.RETURN) {
					e.stopEvent();
						
				var inputnumber = Number(this.fieldSetPage.dom.value); 
						
				if (pageNum = this.readPage(d)) {
						this.pageSize = inputnumber;
						this.limit = inputnumber;
						this.store.baseParams.limit = inputnumber;
						this.doLoad(0);
				}
			}
	}
	
});

/**
 * Ext.grid.GridView Override class definitions
 */
Ext.apply(Ext.grid.GridView.prototype, {

	/***************************************************************************
	 * 用于修正表格被居中时右移的Bug
	 **************************************************************************/

	// private
	initTemplates : function() {
		// add style:{ostyle},{bstyle}
		var ts = this.templates || {};
		if (!ts.master) {
			ts.master = new Ext.Template(
					'<div class="x-grid3" hidefocus="true">',
					'<div class="x-grid3-viewport">',
					'<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
					'<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
					"</div>",
					'<div class="x-grid3-resize-marker">&#160;</div>',
					'<div class="x-grid3-resize-proxy">&#160;</div>', "</div>");
		}

		if (!ts.header) {
			ts.header = new Ext.Template(
					'<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
					'<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
					"</table>");
		}

		if (!ts.hcell) {
			ts.hcell = new Ext.Template(
					'<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}"><div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">',
					this.grid.enableHdMenu
							? '<a class="x-grid3-hd-btn" href="#"></a>'
							: '',
					'{value}<img class="x-grid3-sort-icon" src="',
					Ext.BLANK_IMAGE_URL, '" />', "</div></td>");
		}

		if (!ts.body) {
			ts.body = new Ext.Template('{rows}');
		}

		if (!ts.row) {
			ts.row = new Ext.Template(
					'<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
					'<tbody><tr>{cells}</tr>',
					(this.enableRowBody
							? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>'
							: ''), '</tbody></table></div>');
		}

		if (!ts.cell) {
			ts.cell = new Ext.Template(
					'<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} x-selectable {css}" style="{style}" tabIndex="0" {cellAttr}>',
					'<div class="x-grid3-cell-inner x-grid3-col-{id}"  {attr}>{value}</div>',
					"</td>");
		}

		for (var k in ts) {
			var t = ts[k];
			if (t && typeof t.compile == 'function' && !t.compiled) {
				t.disableFormats = true;
				t.compile();
			}
		}

		this.templates = ts;

		this.tdClass = 'x-grid3-cell';
		this.cellSelector = 'td.x-grid3-cell';
		this.hdCls = 'x-grid3-hd';
		this.rowSelector = 'div.x-grid3-row';
		this.colRe = new RegExp("x-grid3-td-([^\\s]+)", "");
	},

	// private(add firstChild.style.width&judgement row.firstChild)
	updateAllColumnWidths : function() {
		var tw = this.getTotalWidth();
		var clen = this.cm.getColumnCount();
		var ws = [];
		for (var i = 0; i < clen; i++) {
			ws[i] = this.getColumnWidth(i);
		}
		this.innerHd.firstChild.style.width = this.getOffsetWidth();
		this.innerHd.firstChild.firstChild.style.width = tw;
		this.mainBody.dom.style.width = tw;

		for (var i = 0; i < clen; i++) {
			var hd = this.getHeaderCell(i);
			hd.style.width = ws[i];
		}

		var ns = this.getRows(), row, trow;
		for (var i = 0, len = ns.length; i < len; i++) {
			row = ns[i];
			row.style.width = tw;
			if (row.firstChild) {
				row.firstChild.style.width = tw;
				trow = row.firstChild.rows[0];
				for (var j = 0; j < clen; j++) {
					trow.childNodes[j].style.width = ws[j];
				}
			}
		}

		this.onAllColumnWidthsUpdated(ws, tw);
	},

	// private(add firstChild.style.width&judgement row.firstChild)
	updateColumnWidth : function(col, width) {
		var w = this.getColumnWidth(col);
		var tw = this.getTotalWidth();
		this.innerHd.firstChild.style.width = this.getOffsetWidth();
		this.innerHd.firstChild.firstChild.style.width = tw;
		this.mainBody.dom.style.width = tw;
		var hd = this.getHeaderCell(col);
		hd.style.width = w;

		var ns = this.getRows(), row;
		for (var i = 0, len = ns.length; i < len; i++) {
			row = ns[i];
			row.style.width = tw;
			if (row.firstChild) {
				row.firstChild.style.width = tw;
				row.firstChild.rows[0].childNodes[col].style.width = w;
			}
		}

		this.onColumnWidthUpdated(col, w, tw);
	},

	// private(add firstChild.style.width&judgement row.firstChild)
	updateColumnHidden : function(col, hidden) {
		var tw = this.getTotalWidth();
		this.innerHd.firstChild.style.width = this.getOffsetWidth();
		this.innerHd.firstChild.firstChild.style.width = tw;
		this.mainBody.dom.style.width = tw;
		var display = hidden ? 'none' : '';

		var hd = this.getHeaderCell(col);
		hd.style.display = display;

		var ns = this.getRows(), row;
		for (var i = 0, len = ns.length; i < len; i++) {
			row = ns[i];
			row.style.width = tw;
			if (row.firstChild) {
				row.firstChild.style.width = tw;
				row.firstChild.rows[0].childNodes[col].style.display = display;
			}
		}

		this.onColumnHiddenUpdated(col, hidden, tw);
		delete this.lastViewWidth; // force recalc
		this.layout();
	},

	// add function afterRender
	afterRender : function() {
		this.mainBody.dom.innerHTML = this.renderRows() || '&nbsp;';
		this.processRows(0, true);

		if (this.deferEmptyText !== true) {
			this.applyEmptyText();
		}
	},

	// private(add ostyle bstyle value)
	renderUI : function() {

		var header = this.renderHeaders();
		var body = this.templates.body.apply({
			rows : '&nbsp;'
		});
		// added
		var headerDisplay = (this.isHeaderHidden)
				? "display: 'none'"
				: "display: ''";
		var html = this.templates.master.apply({
			body : body,
			header : header,
			ostyle : 'width:' + this.getOffsetWidth() + ';',
			bstyle : 'width:' + this.getTotalWidth() + ';'
		});

		var g = this.grid;

		g.getGridEl().dom.innerHTML = html;

		this.initElements();

		// get mousedowns early
		Ext.fly(this.innerHd).on("click", this.handleHdDown, this);
		this.mainHd.on("mouseover", this.handleHdOver, this);
		this.mainHd.on("mouseout", this.handleHdOut, this);
		this.mainHd.on("mousemove", this.handleHdMove, this);

		this.scroller.on('scroll', this.syncScroll, this);
		if (g.enableColumnResize !== false) {
			this.splitZone = new Ext.grid.GridView.SplitDragZone(g,
					this.mainHd.dom);
		}

		if (g.enableColumnMove) {
			this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g,
					this.innerHd);
			this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
		}

		if (g.enableHdMenu !== false) {
			if (g.enableColumnHide !== false) {
				this.colMenu = new Ext.menu.Menu({
					id : g.id + "-hcols-menu"
				});
				this.colMenu.on("beforeshow", this.beforeColMenuShow, this);
				this.colMenu.on("itemclick", this.handleHdMenuClick, this);
			}
			this.hmenu = new Ext.menu.Menu({
				id : g.id + "-hctx"
			});
			this.hmenu.add({
				id : "asc",
				text : this.sortAscText,
				cls : "xg-hmenu-sort-asc"
			}, {
				id : "desc",
				text : this.sortDescText,
				cls : "xg-hmenu-sort-desc"
			});
			if (g.enableColumnHide !== false) {
				this.hmenu.add('-', {
					id : "columns",
					hideOnClick : false,
					text : this.columnsText,
					menu : this.colMenu,
					iconCls : 'x-cols-icon'
				});
			}
			this.hmenu.on("itemclick", this.handleHdMenuClick, this);

			// g.on("headercontextmenu", this.handleHdCtx, this);
		}

		if (g.trackMouseOver) {
			this.mainBody.on("mouseover", this.onRowOver, this);
			this.mainBody.on("mouseout", this.onRowOut, this);
		}
		if (g.enableDragDrop || g.enableDrag) {
			this.dragZone = new Ext.grid.GridDragZone(g, {
				ddGroup : g.ddGroup || 'GridDD'
			});
		}

		this.updateHeaderSortState();
		
		// \u6dfb\u52a0\u989d\u5916\u7684\u529f\u80fd\u65b9\u6cd5API
		this.increaseAffiliatedCapability(header, body, headerDisplay, html, g);

	},

	increaseAffiliatedCapability : function(header, body, headerDisplay, html,
			g) {
		// ---------------------chenweijie:start--------------------- //
		// \u65b0\u589e\u4e86\u5bfc\u51faExcel\u7684\u529f\u80fd
		var printFlag = g.printable;// \u662f\u5426\u8bbe\u7f6e\u5bfc\u51fa
		if (g.enableHdMenu !== false) {
			if (g.remoteSort) {
				// added by chenweijie:
				// add capability about toggling between global and local sort
				this.sortToggleMenu = new Ext.menu.CheckItem({
					id : "toggleSort",
					text : "\u5168\u5c40\u6392\u5e8f",
					checked : false,
					hideOnClick : false,
					disabled : false
				});
				this.sortToggleMenu.on('checkchange', function(checkItem, checked) {
					// set all globalSortable propteries to false in this grid
					for (var i = 0, len = this.cm.config.length; i < len; i++) {
						var c = this.cm.config[i];
						c.globalSortable = false;
					}
					var colIndex = this.hdCtxIndex;
					var cm = this.cm;
					cm.config[colIndex].globalSortable = checked;
				}, this);
				this.hmenu.add('-', this.sortToggleMenu);
			}

			// add by luzhong control printFlag
			if (printFlag == true) {
				// add printable capability
				this.printMenu = new Ext.menu.CheckItem({
					id : "printable",
					text : "\u6253\u5370",// "print"
					checked : false,
					hideOnClick : false,
					disabled : false
				});
				this.printMenu.on('checkchange', function(checkItem, checked) {
					var colIndex = this.hdCtxIndex;
					var cm = this.cm, ds = this.ds;
					cm.config[colIndex].printable = checked;
				}, this);

				this.hmenu.add('-', this.printMenu);
			}
			this.hmenu.on("beforeshow", function() {
				// retrive the column index
				var colIndex = this.hdCtxIndex;
				var cm = this.cm, ds = this.ds;
				// var sDataIndex = cm.getDataIndex(colIndex);
				var isPrintable = (typeof cm.config[colIndex].printable !== 'undefined')
						? cm.config[colIndex].printable
						: true;
				// add by luzhong control printFlag
				if (printFlag == true) {
					this.printMenu.setChecked(isPrintable, true);
				}
				
				if (g.remoteSort) {
					var isGlobalSortable = (typeof cm.config[colIndex].globalSortable !== 'undefined')
							? cm.config[colIndex].globalSortable
							: false;
					this.sortToggleMenu.setChecked(isGlobalSortable, true);
				}
			}, this);
			// add by luzhong control printFlag
			// close icon of excel-printing
			if(false) {
				// \u5236\u4f5c\u5de6\u53f3\u51c6\u6362\u5de5\u5177\u680f
				me = this;
				this.overallItem = new Ext.util.MixedCollection();// ['grid-print-container',
				// 'grid-print-all-container'];
				// TODO \u6fc0\u6d3b\u5185\u90e8\u5b58\u50a8\u51fd\u6570
				this.overallItem.add('grid-print-container', function(grid,
						store) {
					me.exportExcelInVBA(grid, store);
				});
				// \u5bfc\u51fa\u6240\u6709\u6570\u636e\u65f6\uff0c\u4e0d\u9700\u8981store
				this.overallItem.add('grid-print-all-container', function(grid,
						store) {
					me.exportWholeDataInVBA(grid);
				});
				this.activeItem = {};
				this.activeItem.index = 0;
				this.activeItem.cls = this.overallItem.keys[this.activeItem.index];
				this.activeItem.invokeFunction = this.overallItem
						.get(this.overallItem.keys[this.activeItem.index]);

				var root = Ext.get(document.body);
				var shiftToolBarContainer = root.createChild({
					tag : "div",
					cls : "grid-shift-toolbar-container"
				});

				var toolBarItem = shiftToolBarContainer.createChild({
					tag : "div",
					cls : this.activeItem.cls
				});
				toolBarItem.on('mousedown', function(e) {
					if (this.activeItem.cls === 'grid-print-container') {
						me.exportExcelInVBA(g, g.getStore());
					} else if (this.activeItem.cls === 'grid-print-all-container') {
						me.exportWholeDataInVBA(g);
					}
				}, this);
				if (!Ext.isIE7 && !Ext.isIE6) {
					toolBarItem.setStyle('margin-left', '10px');
				}
				var toolTip = new Ext.ToolTip({
					target : toolBarItem,
					html : (this.activeItem.cls === 'grid-print-container')
							? 'Excel\u5bfc\u51fa'
							: 'Excel\u5168\u90e8\u5bfc\u51fa',
					trackMouse : true
				});

				var rightButton = shiftToolBarContainer.createChild({
					tag : "div",
					cls : "grid-shift-toolbar-container-handle-right"
				});
				var leftButton = shiftToolBarContainer.createChild({
					tag : "div",
					cls : "grid-shift-toolbar-container-handle-left"
				});

				rightButton.on('mousedown', function(e) {
					toolBarItem.removeClass(this.activeItem.cls);
					this.activeItem.index = (this.activeItem.index == this.overallItem
							.getCount()
							- 1) ? 0 : this.activeItem.index + 1;
					this.activeItem.cls = this.overallItem.keys[this.activeItem.index];
					toolBarItem.addClass(this.activeItem.cls);

					toolTip.destroy();
					toolTip = new Ext.ToolTip({
						target : toolBarItem,
						html : (this.activeItem.cls === 'grid-print-container')
								? 'Excel\u5bfc\u51fa'
								: 'Excel\u5168\u90e8\u5bfc\u51fa',
						trackMouse : true
					});
				}, this);
				leftButton.on('mousedown', function(e) {
					toolBarItem.removeClass(this.activeItem.cls);
					this.activeItem.index = (this.activeItem.index == 0)
							? this.overallItem.getCount() - 1
							: this.activeItem.index - 1;
					this.activeItem.cls = this.overallItem.keys[this.activeItem.index];
					toolBarItem.addClass(this.activeItem.cls);

					toolTip.destroy();
					toolTip = new Ext.ToolTip({
						target : toolBarItem,
						html : (this.activeItem.cls === 'grid-print-container')
								? 'Excel\u5bfc\u51fa'
								: 'Excel\u5168\u90e8\u5bfc\u51fa',
						trackMouse : true
					});
				}, this);
				shiftToolBarContainer.setOpacity(.3);
				shiftToolBarContainer.on("mouseover", function(e) {
					shiftToolBarContainer.clearOpacity();
				}, this);
				shiftToolBarContainer.on("mouseout", function(e) {
					shiftToolBarContainer.setOpacity(.3);
				}, this);

				g.on('resize', function() {
					shiftToolBarContainer.setLeftTop(g.getGridEl().getRight()
							- 80, g.getGridEl().getBottom() - 50);
				}, this);
				g.on('beforecollapse', function() {
					shiftToolBarContainer.hide();
				}, this);
				g.on('expand', function() {
					shiftToolBarContainer.show();
				}, this);
				g.on('remove', function() {
					shiftToolBarContainer.remove();
				}, this);
				g.on('destroy', function() {
					shiftToolBarContainer.remove();
				}, this);
				g.on('hide', function() {
					shiftToolBarContainer.hide();
				}, this);
				g.on('show', function() {
					shiftToolBarContainer.show();
				}, this);

				var tabContainer = g.getGridEl().findParent(".x-tab-panel",
						1000000000000, true);// document.body
				if (tabContainer) {
					Ext.getCmp(tabContainer.id).on('tabchange',
							function(tabPanel, activePanel) {

								if (activePanel.getId() === g.getId()) {
									if (activePanel.getId() === g.getId()
											&& activePanel.isVisible()) {
										// \u81ea\u5df1\u5c31\u662f\u7b2c\u4e00\u5c42\u5143\u7d20
										shiftToolBarContainer.show();
									} else {
										shiftToolBarContainer.hide();
									}
								} else {
									var tmp_gridPanel = activePanel.findById(g
											.getId());
									if (tmp_gridPanel
											&& activePanel.isVisible()) {
										// \u81ea\u5df1\u662f\u5b50\u5143\u7d20
										shiftToolBarContainer.show();
									} else {
										shiftToolBarContainer.hide();
									}
								}
								// dom.className
							});
				}

				var windowContainer = g.getGridEl().findParent(".x-window",
						1000000000000, true);// document.body
				if (windowContainer) {
					var windowCmp = Ext.getCmp(windowContainer.id);
					windowCmp.on('hide', function() {
						shiftToolBarContainer.hide();
					});
					windowCmp.on('close', function() {
						shiftToolBarContainer.hide();
					});
					windowCmp.on('show', function() {
						shiftToolBarContainer.show();
					});
					windowCmp.on('minimize', function() {
						shiftToolBarContainer.hide();
					});
					windowCmp.on('move', function() {
						shiftToolBarContainer.setLeftTop(g.getGridEl()
								.getRight()
								- 80, g.getGridEl().getBottom() - 50);
					});
				}

				// DD capacity
				var floatMenuAnchorProxy = new Ext.dd.DDProxy(
						shiftToolBarContainer, {
							group : 'excel-floating-group' + g.id
						});
				var oExcelIconDragZone = new Ext.dd.DDTarget(g,
						'excel-floating-group' + g.id);
			}
		}
		// ---------------------chenweijie: over--------------------- //
	},
	
	// private(add fucniton)
	getOffsetWidth : function() {
		return (this.cm.getTotalWidth() + this.scrollOffset) + 'px';
	},

	// private(add firstChild.style.width)
	updateHeaders : function() {
		this.innerHd.firstChild.innerHTML = this.renderHeaders();
		this.innerHd.firstChild.style.width = this.getOffsetWidth();
		this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();
	},

	// private(add '&nbsp;')
	renderBody : function() {
		var markup = this.renderRows() || '&nbsp;';
		return this.templates.body.apply({
			rows : markup
		});
	},

	// private(add judgement fc.nodeType == 1)
	hasRows : function() {
		var fc = this.mainBody.dom.firstChild;
		return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
	},

	/***************************************************************************
	 * 以上用于修正表格被居中时右移的Bug
	 **************************************************************************/

	// 增加变量用于存储斑马线颜色
	stripleColor : '',
	
	getStripleColor : function() {
		return this.stripleColor;
	},
	// \u91cd\u65b0getRowClass
	getRowClass : function(r, i, p) {
		if (i % 2) {
			p.tstyle = 'width:' + this.getTotalWidth() + ';' + 'background:'
					+ this.getStripleColor();
		} else {
			p.tstyle = 'width:' + this.getTotalWidth();
		}
	},
	getColumnData : function() {
		// build a map for all the columns
		var cs = [], cm = this.cm, colCount = cm.getColumnCount();
		for (var i = 0; i < colCount; i++) {
			var name = cm.getDataIndex(i);
			cs[i] = {
				name : (typeof name == 'undefined'
						? this.ds.fields.get(i).name
						: name),
				renderer : cm.getRenderer(i),
				id : cm.getColumnId(i),
				style : this.getColumnStyle(i),
				dicBind : cm.config[i].dicBind
			};
		}
		return cs;
	},
	
	/***************************************************************************
	 * 添加可编辑表格的验证功能
	 **************************************************************************/
	
	initData : function(ds, cm) {
		if (this.ds) {
			this.ds.un("load", this.onLoad, this);
			this.ds.un("datachanged", this.onDataChange, this);
			this.ds.un("add", this.onAdd, this);
			this.ds.un("remove", this.onRemove, this);
			this.ds.un("update", this.onUpdate, this);
			this.ds.un("clear", this.onClear, this);
		}
		if (ds) {
			ds.on("load", this.onLoad, this);
			ds.on("datachanged", this.onDataChange, this);
			ds.on("add", this.onAdd, this);
			ds.on("remove", this.onRemove, this);
			ds.on("update", this.onUpdate, this);
			ds.on("clear", this.onClear, this);
		}
		this.ds = ds;
		if (this.cm) {
			this.cm.un("configchange", this.onColConfigChange, this);
			this.cm.un("widthchange", this.onColWidthChange, this);
			this.cm.un("headerchange", this.onHeaderChange, this);
			this.cm.un("hiddenchange", this.onHiddenChange, this);
			this.cm.un("columnmoved", this.onColumnMove, this);
			this.cm.un("columnlockchange", this.onColumnLock, this);
		}
		if (cm) {
			cm.on("configchange", this.onColConfigChange, this);
			cm.on("widthchange", this.onColWidthChange, this);
			cm.on("headerchange", this.onHeaderChange, this);
			cm.on("hiddenchange", this.onHiddenChange, this);
			cm.on("columnmoved", this.onColumnMove, this);
			cm.on("columnlockchange", this.onColumnLock, this);
		}
		this.cm = cm;
		// add cell validate event
		this.addEvents('cellvalidate');
	},
	
	doRender : function(cs, rs, ds, startRow, colCount, stripe) {
		var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount - 1;
		var tstyle = 'width:' + this.getTotalWidth() + ';';
		// buffers
		var buf = [], cb, c, p = {}, rp = {
			tstyle : tstyle
		}, r;
		for (var j = 0, len = rs.length; j < len; j++) {
			r = rs[j];
			cb = [];
			var rowIndex = (j + startRow);
			for (var i = 0; i < colCount; i++) {
				c = cs[i];
				p.id = c.id;
				p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last
						? 'x-grid3-cell-last '
						: '');
				p.attr = p.cellAttr = "";
				// \u5b57\u5178\u6570\u636e\u7ed1\u5b9a, Gaoshang
				var value = r.data[c.name];
				if (c.dicBind) {
					value = Wonders.grid.transformDicData(value, c.dicBind);
				}
				p.value = c.renderer(value, p, r, rowIndex, i, ds);
				p.style = c.style;
				if (p.value == undefined || p.value === "")
					p.value = "&#160;";
				if (r.dirty && typeof r.modified[c.name] !== 'undefined') {
					p.css += ' x-grid3-dirty-cell';
				}
				// call cell validate event
				if (!this
						.fireEvent("cellvalidate", this, p, c, rowIndex, i, ds)) {
					p.css += ' x-form-invalid';
					// p.validatecss = 'x-form-invalid';
				}
				cb[cb.length] = ct.apply(p);
			}
			var alt = [];
			if (stripe && ((rowIndex + 1) % 2 == 0)) {
				alt[0] = "x-grid3-row-alt";
			}

			if (r.dirty) {
				alt[1] = " x-grid3-dirty-row";
			}
			rp.cols = colCount;
			if (this.getRowClass) {
				alt[2] = this.getRowClass(r, rowIndex, rp, ds);
			}
			rp.alt = alt.join(" ");
			rp.cells = cb.join("");
			buf[buf.length] = rt.apply(rp);
		}
		return buf.join("");
	},
	
	//多次后台请求导出全部数据,前台导出,支持2W数据量
	exportWholeDataInVBA:function(grid){
		var colModel=grid.getColumnModel();
		var count=colModel.getColumnCount();
		var fields=[];
		fields.push("<input type='checkbox' hidefocus='true' checked='checked' onclick='checkExcelAll(this,"+"\""+grid.getId()+"\""+")' value='' id='d_c_0' /><label style='width:100px;' hidefocus='true' for='d_c_0'>&nbsp;&nbsp;"+"全选"+"</label>");
		fields.push("<br/><br/>");
		//支持导出列
		var id="";
		var title="";
		var dataIndex="";
		var j=0;
		for(var i=0;i<count;i++){
			id=colModel.getColumnId(i);
			if(id=="checker" || id=="radio" || id=="rowNumber"){
				continue;
			}
			title=colModel.getColumnHeader(i);
			dataIndex=colModel.getDataIndex(i);
			if(colModel.config[i].exportColumn == true){
				j++;
				fields.push("<input type='checkbox' hidefocus='true' name='exports' checked='checked' value='"+dataIndex+"' id='g_c_"+id+"' /><label style='width:100px;' hidefocus='true' for='g_c_"+id+"'>&nbsp;&nbsp;"+title+"</label>");  
				if(j%2==0){
                    fields.push("<br/><br/>");
                }else{
                	fields.push("&nbsp;&nbsp;&nbsp;&nbsp;");
                }
			}
		}
		//选择需要导出的列
		var win = new Ext.Window({title:"\u9009\u62e9\u9700\u8981\u5bfc\u51fa\u7684\u5217",modal:true,layout:"anchor",autoScroll: true,
	    height:320,width:300,buttonAlign: 'center',html:fields.join(""),
	    buttons: [{text: '\u786e\u5b9a', handler: function(){//确定
	    	Ext.MessageBox.progress("Excel\u5bfc\u51fa",//Excel导出
					"\u5b8c\u6574\u5bfc\u51fa...", "\u83b7\u53d6\u6570\u636e...");	//完整导出//正在导出
			Ext.MessageBox.updateProgress(0, "\u6b63\u5728\u521d\u59cb\u5316\u53c2\u6570...");//正在初始化参数
			//选择导出列
	    	var dom=win.el.dom;
	    	var checkboxs=dom.getElementsByTagName("INPUT");
	    	var ck=null;
	    	var exportFields=[];
	    	for(var i=1,l=checkboxs.length;i<l;i++){
	    		ck=checkboxs[i];
	    		ck.checked ? exportFields.push(ck.value) : null;
	    	}
	    	//-----------------------------------------------------------------------	
			//构建请求store
		    var store=grid.getStore();
	    	//注意拷贝参数,直接赋值导致导出excel后grid下一页出错
	    	var src=store.baseParams;
	    	var target={};
	    	for(var px in src){
	    		target[px]=src[px];
	    	}
	    	
		  	var newStore= new Ext.data.Store({
		  		autoLoad:false,
				url : store.proxy.conn.url,
				pruneModifiedRecords : false,
				remoteSort : store.remoteSort,
				sortInfo : store.sortInfo,
				reader : new Ext.data.JsonReader(store.reader.meta, store.reader.recordType),
				baseParams : target
			});
			//-----------------------------------------------------------------------	
			//创建导出对象
			var exporter=new ExcelExporter();
			if(exporter.init(exportFields,grid,newStore)==false){
				return;
			}
			//-----------------------------------------------------------------------	
			//导出标题
			exporter.exportCaption();
			//导出列标题
			exporter.exportHeader();
			
			var params={
				start:0,
				exporter:exporter,
				exceptionCount:0
			};
			//加载数据回调函数
			var callback=function(st,para){
				var epter=para.exporter;
				//导出当前store数据,内部包含到处分组表格标题及分组统计数据
				epter.exportRecord();

				var size=st.getCount();
				var total=st.getTotalCount();
				//释放内存
				st.data.clear();
				
				var start=para.start+size;
				para.start=start;
			
				Ext.MessageBox.updateProgress(start/total, "\u6b63\u5728\u5bfc\u51fa"+start+"/"+total+"...");//正在导出
				
				if(start < total){
					st.baseParams.start=start;
					st.load({
						params:{start:start}
					});
				}else{
					//导出全局统计数据
					epter.exportSummary();
					Ext.MessageBox.hide();
					epter.destroy();
					params=null;
					st=null;
				}
			}
			//-----------------------------------------------------------------------	
			//注册加载数据监听器
			newStore.on("load",function(st,records){
				var par=params;
				par.exceptionCount=0;
				callback(st,par);
			});	
			//-----------------------------------------------------------------------	
			//网络错误导致导出请求失败,处理失败请求
			newStore.on("loadexception",function(){
				var par=params;
				var st=newStore;
				par.exceptionCount++;
				if(par.exceptionCount===30){//请求异常//到处请求连续10发生异常,继续发送导出请求么?
					Ext.MessageBox.confirm("\u8bf7\u6c42\u5f02\u5e38","\u5bfc\u51fa\u8bf7\u6c42\u8fde\u7eed30\u6b21\u51fa\u73b0\u5f02\u5e38,\u7ee7\u7eed\u5c1d\u8bd5\u53d1\u9001\u5bfc\u51fa\u8bf7\u6c42\u4e48?",function(btn,text){
						if(btn=="yes"){
							par.exceptionCount=0;
							Ext.MessageBox.progress("Excel\u5bfc\u51fa",//Excel导出
													"\u5b8c\u6574\u5bfc\u51fa...", "\u83b7\u53d6\u6570\u636e...");
							Ext.MessageBox.updateProgress(par.start/st.getTotalCount(), "\u6b63\u5728\u5bfc\u51fa"+par.start+"/"+st.getTotalCount()+"...");//正在导出
							setTimeout(function(){st.reload();}, 100);
						}else{
							parm.exporter.destroy(true);
							Ext.MessageBox.hide();
							st=null;
							par=null;
						}
					});
					return;
				}
				setTimeout(function(){st.reload();}, 100);
			});	
			//-----------------------------------------------------------------------	
			//请求参数
			newStore.baseParams.start=0;
			newStore.baseParams.limit=exporter.pageSize;
			//加载数据
		    newStore.load();
			win.close();
	    }},
	    	{text: '\u53d6\u6d88', handler: function(){win.close();}}]//取消
		});	
		win.show();
	},
	
	//导出选取
	exportSelectExcelInVBA:function(grid){
		//获取选择
		var sns= grid.getSelectionModel().getSelections();
		if(sns.length==0){
			Wonders.Msg.info("\u672a\u9009\u53d6\u8bb0\u5f55\uff0c\u8bf7\u5148\u9009\u53d6\u8bb0\u5f55\uff01");
			return;
		}
		var newStore = new Ext.data.Store();
		newStore.add(sns);
		this.exportExcelInVBA(grid,newStore);
	},
	
	//导出本页(包含分组表格)
	exportExcelInVBA : function(grid, oStore) {
		if (oStore.getRange().length == 0) {
			Wonders.Msg.info("\u672a\u627e\u5230\u8bb0\u5f55\uff0c\u8bf7\u5148\u6267\u884c\u67e5\u8be2\uff01");
			return;
		}
		//-----------------------------------------------------------------------	
		var colModel=grid.getColumnModel();
		var count=colModel.getColumnCount();
		var fields=[];
		fields.push("<input type='checkbox' hidefocus='true' checked='checked' onclick='checkExcelAll(this,"+"\""+grid.getId()+"\""+")' value='' id='d_c_0' /><label style='width:100px;' hidefocus='true' for='d_c_0'>&nbsp;&nbsp;"+"全选"+"</label>");
		fields.push("<br/><br/>");
		//支持导出列
		var id="";
		var title="";
		var dataIndex="";
		var j=0;
		for(var i=0;i<count;i++){
			id=colModel.getColumnId(i);
			if(id=="checker" || id=="radio" || id=="rowNumber"){
				continue;
			}
			title=colModel.getColumnHeader(i);
			dataIndex=colModel.getDataIndex(i);
			if(colModel.config[i].exportColumn == true){
				j++;
		        fields.push("<input type='checkbox' hidefocus='true' name='exports' checked='checked' value='"+dataIndex+"' id='g_c_"+id+"' /><label style='width:100px;' hidefocus='true' for='g_c_"+id+"'>&nbsp;&nbsp;"+title+"</label>");  
                if(j%2==0){
                    fields.push("<br/><br/>");
                }else{
                	fields.push("&nbsp;&nbsp;&nbsp;&nbsp;");
                }
			}
		}
		//-----------------------------------------------------------------------	
		var win = new Ext.Window({title:"\u9009\u62e9\u9700\u8981\u5bfc\u51fa\u7684\u5217",modal:true,layout:"anchor",autoScroll: true,
	    height:320,width:300,buttonAlign: 'center',html:fields.join(""),
	    buttons: [{text: '\u786e\u5b9a', handler: function(){
	    	Ext.MessageBox.wait("\u6b63\u5728\u521d\u59cb\u5316\u53c2\u6570...","Excel\u5bfc\u51fa");//正在初始化参数//Excel导出
			//选择导出列
	    	var dom=win.el.dom;
	    	var checkboxs=dom.getElementsByTagName("INPUT");
	    	var ck=null;
	    	var exportFields=[];
	    	for(var i=1,l=checkboxs.length;i<l;i++){
	    		ck=checkboxs[i];
	    		ck.checked ? exportFields.push(ck.value) : null;
	    	}
			
			//-----------------------------------------------------------------------	
			var exporter=new ExcelExporter();
			if(exporter.init(exportFields,grid,oStore)==false){
				return;
			}
			//-----------------------------------------------------------------------	
			Ext.MessageBox.updateText("\u6b63\u5728\u5bfc\u51fa...");//正在导出
			//表格标题
			exporter.exportCaption();
			//表格列标题
			exporter.exportHeader();
			//表格记录,包含分组标题及分组统计
			exporter.exportRecord();
			//表格全局统计
			exporter.exportSummary();
			//销毁
			exporter.destroy();
			Ext.MessageBox.hide();
			win.close();
	    }},
	    	{text: '\u53d6\u6d88', handler: function(){win.close();}}]
		});	
		win.show();
	},
	
	//后台server导出
	exportWholeDataInServer:function(grid){
		var totalCount = grid.getStore().getTotalCount();
		if (totalCount == 0) {
			Wonders.Msg.info("\u672a\u627e\u5230\u8bb0\u5f55\uff0c\u8bf7\u5148\u6267\u884c\u67e5\u8be2\uff01");
			return;
		}	
		//-----------------------------------------------------------------------	
		var colModel=grid.getColumnModel();
		var count=colModel.getColumnCount();
		var fields=[];
		fields.push("<input type='checkbox' hidefocus='true' checked='checked' onclick='checkExcelAll(this,"+"\""+grid.getId()+"\""+")' value='' id='d_c_0' /><label style='width:100px;' hidefocus='true' for='d_c_0'>&nbsp;&nbsp;"+"全选"+"</label>");
		fields.push("<br/><br/>");
		//支持导出列
		var id="";
		var title="";
		var dataIndex="";
		var j=0;
		for(var i=0;i<count;i++){
			id=colModel.getColumnId(i);
			if(id=="checker" || id=="radio" || id=="rowNumber"){
				continue;
			}
			title=colModel.getColumnHeader(i);
			dataIndex=colModel.getDataIndex(i);
			if(colModel.config[i].exportColumn == true){
				j++;
				fields.push("<input type='checkbox' hidefocus='true' name='exports' checked='checked' value='"+dataIndex+"' id='g_c_"+id+"' /><label style='width:100px;' hidefocus='true' for='g_c_"+id+"'>&nbsp;&nbsp;"+title+"</label>");  
				if(j%2==0){
					fields.push("<br/><br/>");
				}else{
					fields.push("&nbsp;&nbsp;&nbsp;&nbsp;");
				}
			}
		}
		//-----------------------------------------------------------------------	
		var win = new Ext.Window({title:"\u9009\u62e9\u9700\u8981\u5bfc\u51fa\u7684\u5217",modal:true,layout:"anchor",autoScroll: true,
	    height:320,width:300,buttonAlign: 'center',html:fields.join(""),
	    buttons: [{text: '\u786e\u5b9a', handler: function(){
	    	//选择导出列
	    	var dom=win.el.dom;
	    	var checkboxs=dom.getElementsByTagName("INPUT");
	    	var ck=null;
	    	var exportFields=[];
	    	var exportHeaders=[];
	    	var vs="";
	    	for(var i=1,l=checkboxs.length;i<l;i++){
	    		ck=checkboxs[i];
	    		if(ck.checked){
	    			vs=ck.value.split(",");
	    			exportFields.push(vs[0]);
	    			exportHeaders.push(vs[1]);
	    		}
	    	}
	    	
	    	var html="";
	    	var g=grid;
	    	 var params = grid.getStore().baseParams;
	    	var form = document.getElementById(g.id+'_exportAllDataForm');
			for (var param in params){
				html+="<input type='hidden' name='"+param+"' value='"+params[param]+"' />";
			}
			html+="<input type='hidden' name='gridId' value='"+g.id+"' />";
			html+="<input type='hidden' name='columnHeads' value='"+exportHeaders.join(',')+"' />";
			html+="<input type='hidden' name='columnIndexs' value='"+exportFields.join(',')+"' />";
			form.innerHTML=html;
			form.submit();
			win.close();
	    }},
	    	{text: '\u53d6\u6d88', handler: function(){win.close();}}]
		});	
		win.show();
	},

	// private
	extractHtmlContent : function(htmlFragment, realContent) {
		try {
			if (htmlFragment.indexOf('<') >= 0) {
				htmlFragment = htmlFragment.substring(htmlFragment.indexOf('<')
						+ 1);
			} else {
				return (realContent !== '') ? realContent : htmlFragment;
			}
			if (htmlFragment.indexOf('>') >= 0) {
				if (htmlFragment.indexOf('<') - htmlFragment.indexOf('>') > 1) {
					realContent += htmlFragment.substring(htmlFragment
							.indexOf('>')
							+ 1, htmlFragment.indexOf('<'));
				}
			}
			return this.extractHtmlContent(htmlFragment, realContent);
		} catch (e) {
			return htmlFragment;
		}
	},
	
	/***************************************************************************
	 * 用于修正autoHeight时滚动条不显示的Bug
	 **************************************************************************/
	layout : function(){
		if(!this.mainBody){
			return; // not rendered
		}
		var g = this.grid;
		var c = g.getGridEl(), cm = this.cm,
				expandCol = g.autoExpandColumn,
				gv = this;

		var csize = c.getSize(true);
		var vw = csize.width;

		if(vw < 20 || (csize.height < 20 && csize.height > 0)){ // display: none?
			return;
		}

		if(g.autoHeight){
			this.scroller.setSize(vw, vh);
		}else{
			this.el.setSize(csize.width, csize.height);

			var hdHeight = this.mainHd.getHeight();
			var vh = csize.height - (hdHeight);

			this.scroller.setSize(vw, vh);
		}
		if(this.innerHd){
			this.innerHd.style.width = (vw)+'px';
		}
		if(this.forceFit){
			if(this.lastViewWidth != vw){
				this.fitColumns(false, false);
				this.lastViewWidth = vw;
			}
		} else {
			this.autoExpand();
			this.syncHeaderScroll();
		}
		if(g.autoHeight){
			if(this.scroller.dom.scrollHeight>this.scroller.dom.clientHeight
				&&this.scroller.dom.scrollWidth>this.scroller.dom.clientWidth){
				this.scroller.setSize(vw, this.scroller.dom.scrollHeight+this.scrollOffset);
			}
			this.el.dom.style.height = this.mainWrap.getHeight() + 'px';
		}
		this.onLayout(vw, vh);
	},

	/***************************************************************************
	 * 用于修正forceFit时右边的多余空白
	 **************************************************************************/
    fitColumns : function(preventRefresh, onlyExpand, omitColumn){
        var cm = this.cm, leftOver, dist, i;
        var tw = cm.getTotalWidth(false);
        var aw = this.grid.getGridEl().getWidth(true)-((this.scroller!=null&&(this.scroller.dom.scrollHeight>this.scroller.dom.clientHeight))?this.scrollOffset:0);

        if(aw < 20){ // not initialized, so don't screw up the default widths
            return;
        }
        var extra = aw - tw;

        if(extra === 0){
            return false;
        }

        var vc = cm.getColumnCount(true);
        var ac = vc-(typeof omitColumn == 'number' ? 1 : 0);
        if(ac === 0){
            ac = 1;
            omitColumn = undefined;
        }
        var colCount = cm.getColumnCount();
        var cols = [];
        var extraCol = 0;
        var width = 0;
        var w;
        for (i = 0; i < colCount; i++){
            if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
                w = cm.getColumnWidth(i);
                cols.push(i);
                extraCol = i;
                cols.push(w);
                width += w;
            }
        }
        var frac = (aw - cm.getTotalWidth())/width;
        while (cols.length){
            w = cols.pop();
            i = cols.pop();
            cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
        }

        if((tw = cm.getTotalWidth(false)) > aw){
            var adjustCol = ac != vc ? omitColumn : extraCol;
             cm.setColumnWidth(adjustCol, Math.max(1,
                     cm.getColumnWidth(adjustCol)- (tw-aw)), true);
        }

        if(preventRefresh !== true){
            this.updateAllColumnWidths();
        }


        return true;
    },
    
    refresh : function(headersToo){
        this.fireEvent("beforerefresh", this);
        this.grid.stopEditing(true);

        var result = this.renderBody();
        this.mainBody.update(result);

        if(headersToo === true){
            this.updateHeaders();
            this.updateHeaderSortState();
        }
        this.processRows(0, true);
        if(this.forceFit) {
        	this.fitColumns(false, false);
        }
        this.layout();
        this.applyEmptyText();
        this.fireEvent("refresh", this);
    },
    
    // 点击列头排序时，编辑内容不清空
    onHeaderClick : function(g, index){		
        g.stopEditing(false);
        if(this.headersDisabled || !this.cm.isSortable(index)){
            return;
        }
        g.store.sort(this.cm.getDataIndex(index));
    }
});

/**
 * @ignore
 */
function Delay(timeout, func) {
	this.index = Delay.Instants.length;
	Delay.Instants[this.index] = this;
	this.timeout = timeout;
	this.func = func;
	this.args = [];
	for (var i = 2; i < arguments.length; i++) {
		this.args[this.args.length] = arguments[i];
	}
}

/**
 * @ignore
 */
Delay.prototype.run = function() {
	setTimeout("DelayCall(" + this.index + ")", this.timeout);
};

/**
 * @ignore
 */
Delay.prototype.execute = function() {
	this.func.apply(this, this.args);
};

Delay.Instants = [];

/**
 * @ignore
 */
function DelayCall(index) {
	Delay.Instants[index].execute();
}

function ExcelExporter(){}

//默认前台导出页大小
ExcelExporter.prototype.pageSize=100;

ExcelExporter.prototype.init=function(exportFields,grid,store){
		try{
			  this.oXL = new ActiveXObject('Excel.Application');
			  this.oWB = this.oXL.Workbooks.Add();
			  this.oWB.BuiltinDocumentProperties("Title") = "New Name";
			  this.oSheet = this.oWB.ActiveSheet;
		}catch (e) {//初始化失败//如已安装Excel,请调整IE安全级别:<br>工具 → Internet选项 → 安全 → 自定义级别 → 对没有标记为安全的ActiveX进行初始化和脚本运行 → 启用
			  Ext.MessageBox.alert("\u521d\u59cb\u5316\u5931\u8d25","\u5982\u5df2\u5b89\u88c5Excel,\u8bf7\u8c03\u6574IE\u5b89\u5168\u7ea7\u522b:<br>\u5de5\u5177 \u2192 Internet\u9009\u9879 \u2192 \u5b89\u5168 \u2192 \u81ea\u5b9a\u4e49\u7ea7\u522b \u2192 \u5bf9\u6ca1\u6709\u6807\u8bb0\u4e3a\u5b89\u5168\u7684ActiveX\u8fdb\u884c\u521d\u59cb\u5316\u548c\u811a\u672c\u8fd0\u884c \u2192 \u542f\u7528");
			  return false;
		}
		this.exportFields=exportFields;
		this.caption=grid.title;
		this.store=store || grid.getStore();
//--------------------------------以下初始化数据-----------------------------------		
		this.exportHeaders=[];
		this.columnIndex=[];
		this.fieldRenders=[];

		this.summary=false;//数据结构:[{type:'sum',value:[]},false,{}]
		this.groupSummary=false;//数据结构:[{type:'sum',value:[]},false,{}]
		this.group=grid.groupField ? grid.groupField : false;//表格分组	

		this.summaryText=grid.summaryText;//统计文本
		this.groupSummaryText=grid.subSummaryText;//分组统计文本	
//-----------------------------------------------------------------------				
		var ps=grid.plugins;//because there 2 plugin
		ps && ((ps.length > 0 && ps[0].toggleSummary) || ps.toggleSummary) ? 	 this.summary=[] : null;//判断全局统计,需更进一步规范
		ps && ((ps.length > 1 && ps[1].updateSummaryData) || ps.updateSummaryData) ? this.groupSummary=[] : null;//判断分组统计,需更进一步规范
//-----------------------------------------------------------------------
		var colModel=grid.getColumnModel();
		var colConfig=colModel.config;

		var i=0;
		var j=0;
		var config=null;
		var type=false;
		var dicBind=false;
		var renderer=false;
		var length=this.exportFields.length;
		var columnLen=colConfig.length;
		for(i=0;i<length;i++){
			for(j=0;j<columnLen;j++){
				config=colConfig[j];
				if(config.dataIndex==this.exportFields[i]){
					this.exportHeaders.push(config.header);
					this.columnIndex.push(j);
					dicBind=config.dicBind;
					renderer=config.renderer;
					this.fieldRenders.push(dicBind || renderer ? {dicBind:dicBind ? dicBind : false,renderer:renderer ? renderer : false} : false);
					type=config.summaryType;
					this.summary ? this.summary.push(type ? {type:type,value:0,count:0,precision:config.summaryDecimalPrecision} : false) : null;
					this.groupSummary ? this.groupSummary.push(type ? {type:type,value:0,count:0,precision:config.summaryDecimalPrecision} : false) : null;
					break;
				}
			}
		}
//-----------------------------------------------------------------------
		if(this.group){
			config=colConfig[colModel.findColumnIndex(this.group)];
			dicBind=config.dicBind;
			renderer=config.renderer;
			this.group={header:config.header,field:this.group,dicBind:dicBind ? dicBind :false,renderer:renderer ? renderer : false};//数据结构:[field:'',dicBind:false,renderer:false]
		}
		
		this.rowIndex=1;
		return true;
}

ExcelExporter.prototype.exportCaption=function(){
	var sheet=this.oSheet;
	var range = sheet.Range(sheet.Cells(this.rowIndex, 1), sheet.Cells(this.rowIndex, this.exportHeaders.length));
	range.Merge();
	range.Font.Bold = true;//单元格字体黑体
	range.Font.Size=16;//单元格字体大小
	range.EntireColumn.AutoFit();
	range.HorizontalAlignment = 3;//居中对齐
	//range.VerticalAlignment = 2;//居中对齐
	sheet.Cells(this.rowIndex++, 1).value = this.caption;
	range=null;
};

ExcelExporter.prototype.exportHeader=function(){
	var cell=null;
	var sheet=this.oSheet;
	var headers=this.exportHeaders;
	var length=headers.length;
	var range=sheet.Range(sheet.Cells(this.rowIndex,1),sheet.Cells(this.rowIndex,length+1));
	range.Font.Bold = true;//单元格字体黑体
	range.Font.Size=14;//单元格字体大小
	range.EntireColumn.AutoFit();
	range.HorizontalAlignment = 3;//居中对齐
	//range.VerticalAlignment = 2;//居中对齐
	for(var k=0;k<length;k++){
		cell = sheet.Cells(this.rowIndex, k + 1);
		cell.value=""+headers[k];
	}
	cell=null;
	range=null;
	this.rowIndex++;
};

ExcelExporter.prototype.exportRecord=function(){
	var store=this.store;
	var count=store.getCount();
	if(count < 1){
		return;
	}
	
	var fields=this.exportFields;//导出字段
	var renders=this.fieldRenders;//导出字段对应渲染容器
	var columnIndex=this.columnIndex;//导出字段所在列索引

	var group=this.group;//导出分组标题信息
	var summary=this.summary;//导出全局统计信息
	var groupSummary=this.groupSummary;//导出分组统计信息

	var fLen=fields.length;
	
	var i=0;
	var j=0;
	
	var value="";
	var cell=null;

	var first=null;
	var record=null;
	for(i=0;i<count;i++){
		record=store.getAt(i);
		if(i==0 && group){//导出第一分组头部
			first=record;
			this.exportGroupHeader(record);
		}
		
		if(group && first.get(group.field)!=record.get(group.field)){
			groupSummary ? this.exportGroupSummary() : null;//导出上一分组统计信息
			first=record;
			this.exportGroupHeader(record);//导出分组头部
		}
		
		for(j=0;j<fLen;j++){
			cell=this.oSheet.Cells(this.rowIndex,j+1);
			cell.NumberFormatLocal = "@";
			value=record.get(fields[j]);
			summary && summary[j] ? this.calculateSummary(summary[j],value) : null;
			groupSummary && groupSummary[j] ? this.calculateSummary(groupSummary[j],value)  : null;
			if(renders[j]){//数据渲染
				renders[j].dicBind ? value = Wonders.grid.transformDicData(value, renders[j].dicBind) : null;
				renders[j].renderer ? value = this.html2plain(renders[j].renderer(value,false,record,i,columnIndex[j],store)) : null;
			}
			cell.WrapText=false;
			cell.value=this.extractHtmlContent(""+value,"");;
		}
		this.rowIndex++; 
	}
	groupSummary ? this.exportGroupSummary() : null;//导出最后分组统计信息
	cell=null;
};

ExcelExporter.prototype.calculateSummary=function(summary,target){
	var type=summary.type;
	var src=summary.value;
	if(type=="max"){
		src < target  ? summary.value=target : null;
	}else{
		if(type=="min"){
			src > target  ? summary.value=target : null;
		}else{
			if(type=="count"){
				summary.count++;
			}else{
				summary.count++;
				summary.value+=Ext.num(target,0);
			}
		}
	}
};

ExcelExporter.prototype.exportGroupHeader=function(record){
	var sheet=this.oSheet;
	var range = sheet.Range(sheet.Cells(this.rowIndex, 1), sheet.Cells(this.rowIndex, this.exportHeaders.length));
	range.Merge();
	range.Font.Bold = true;//单元格字体
	
	var g=this.group;
	var value=record.get(g.field);
	g.dicBind ? value=Wonders.grid.transformDicData(value,g.dicBind) : null;
	g.renderer ? value=this.html2plain(g.renderer(value,false,record,-1,-1,this.store)): null;
	
	sheet.Cells(this.rowIndex++, 1).value =g.header+":"+this.extractHtmlContent(""+value,""); ;
	range=null;
	return null;
};

ExcelExporter.prototype.exportGroupSummary=function(){
	var data=this.groupSummary;
	if(data===false){
		return null;
	}
	
	var length=data.length;
	
	var sheet=this.oSheet;
	var range = sheet.Range(sheet.Cells(this.rowIndex, 1), sheet.Cells(this.rowIndex,length));
	range.Merge();
	range.Font.Bold = true;//单元格字体
	sheet.Cells(this.rowIndex++, 1).value =this.groupSummaryText ;

	var render=null;
	var cell=null;
	var smy=null;
	var value="";
	for(var i=0;i<length;i++){
		smy=data[i];
		if(smy!==false){
			cell=sheet.Cells(this.rowIndex,i+1);
			cell.NumberFormatLocal = "@";
			if(smy.type=="count"){
				value=""+smy.count;
			}else{
				value=smy.value;
				smy.type=="average" ? value=value/smy.count : null;
				value=Number(value).toFixed(smy.precision);
				render=this.fieldRenders[i];
				render.dicBind ? value=Wonders.grid.transformDicData(value,render.dicBind) : null;//in fact i do not think it a config
				render.renderer ? value=this.html2plain(render.renderer(value,false,null,-1,-1,this.store)): null;//it can exists here
			}
			cell.value=this.extractHtmlContent(value,"");;
			smy.value=0;
			smy.count=0;
		}
	}
	range=null;
	cell=null;
	this.rowIndex++;
	return null;
};

ExcelExporter.prototype.exportSummary=function(){
	var data=this.summary;
	if(data===false){
		return null;
	}
	
	var length=data.length;

	var sheet=this.oSheet;
	var range = sheet.Range(sheet.Cells(this.rowIndex, 1), sheet.Cells(this.rowIndex, this.exportHeaders.length));
	range.Merge();
	range.Font.Bold = true;//单元格字体
	sheet.Cells(this.rowIndex++, 1).value = this.summaryText;

	var render=null;
	var cell=null;
	var smy=null;
	var value="";
	for(var i=0;i<length;i++){
		smy=data[i];
		if(smy!==false){
			cell=sheet.Cells(this.rowIndex,i+1);
			cell.NumberFormatLocal = "@";
			if(smy.type=="count"){
				value=""+smy.count;
			}else{
				value=smy.value;
				smy.type=="average" ? value=value/smy.count : null;
				value=Number(value).toFixed(smy.precision);
				render=this.fieldRenders[i];
				render.dicBind ? value=Wonders.grid.transformDicData(value,render.dicBind) : null;//in fact i do not think it a config
				render.renderer ? value=this.html2plain(render.renderer(value,false,null,-1,-1,this.store)): null;//it can exists here
			}
			cell.value=this.extractHtmlContent(value,"");
			smy.value=0;
			smy.count=0;
		}
	}
	range=null;
	cell=null;
	this.rowIndex++;
	return null;
};

ExcelExporter.prototype.html2plain = function(value) {
	value = value.replace(new RegExp('<br>', 'ig'), '\n');
	value = value.replace(new RegExp('<([^>]*)>', 'g'), '');
	value = value.replace(new RegExp('&quot;', 'g'), '"');
	value = value.replace(new RegExp('&amp;', 'g'), '&');
	value = value.replace(new RegExp('&lt;', 'g'), '<');
	value = value.replace(new RegExp('&gt;', 'g'), '>');
	value = value.replace(new RegExp('&nbsp;', 'g'), ' ');
	value = value.replace(new RegExp('&#34;', 'g'), '"');
	value = value.replace(new RegExp('&#38;', 'g'), '&');
	value = value.replace(new RegExp('&#60;', 'g'), '<');
	value = value.replace(new RegExp('&#62;', 'g'), '>');
	value = value.replace(new RegExp('&#160;', 'g'), ' ');
	return value;
};

ExcelExporter.prototype.extractHtmlContent = function(htmlFragment, realContent) {
	try {
		if (htmlFragment.indexOf('<') >= 0) {
			htmlFragment = htmlFragment
					.substring(htmlFragment.indexOf('<') + 1);
		} else {
			return (realContent !== '') ? realContent : htmlFragment;
		}
		if (htmlFragment.indexOf('>') >= 0) {
			if (htmlFragment.indexOf('<') - htmlFragment.indexOf('>') > 1) {
				realContent += htmlFragment.substring(htmlFragment.indexOf('>')
						+ 1, htmlFragment.indexOf('<'));
			}
		}
		return this.extractHtmlContent(htmlFragment, realContent);
	} catch (e) {
		return htmlFragment;
	}
};

ExcelExporter.prototype.destroy=function(exceptionFlag){
	this.summary=null;
	this.group=null;
	this.groupSummary=null;
	this.exportHeaders=null;
	this.exportFields=null;
	this.fieldRenders=null;
	this.columnIndex=null;
	this.summaryText=null;
	this.groupSummaryText=null;
	this.rowIndex=1;
	
	this.oSheet.Columns.AutoFit();
	this.oXL.Visible = exceptionFlag===true ? false : true;
	this.oXL.UserControl = true;
	this.oXL=null;
	this.oWB = null;
	this.oSheet = null;
		
	setTimeout(CollectGarbage, 100);//DO THE BEST
};

// fix bug for checkbox select
Ext.apply(Ext.grid.CheckboxSelectionModel.prototype, {

	/* =======是否保留已选中状态====== */
	autoMaintainSelected : true,
	/* =======指定只能通过checkbox进行选中====== */
	checkboxSelectOnly: false,
	
	handleMouseDown : function(g, rowIndex, e) {
		if (e.button !== 0 || this.isLocked()) {
			return;
		};
		var view = this.grid.getView();
		if (e.shiftKey && this.last !== false) {
			var last = this.last;
			this.selectRange(last, rowIndex, e.ctrlKey);
			this.last = last; // reset the last
			view.focusRow(rowIndex);
		} else {
			var isSelected = this.isSelected(rowIndex);
			if (e.ctrlKey && isSelected) {
				this.deselectRow(rowIndex);
			} else if (!isSelected || this.getCount() > 1) {
				//额外判断
				if(!this.checkboxSelectOnly){
					//保留以选中状态代码
					if (this.autoMaintainSelected) {
						this.selectRow(rowIndex, true);
					} else {
						this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
					}
				}else{
					//保留ctrl、shift按键效果
					if(e.ctrlKey || e.shiftKey){
						this.selectRow(rowIndex, true);
					}
				}
				view.focusRow(rowIndex);
			}
		}
	}
});


/**
 * 扩展Ext.grid.EditorGridPanel，增加property
 */
Ext.apply(Ext.grid.EditorGridPanel.prototype, {
	property:'',	
	getProperty : function(){
		return this.property;
	}		
});

/**
 * add event formatedit for private use
 */
Ext.apply(Ext.grid.EditorGridPanel.prototype, {
		// private
    initComponent : function(){
        Ext.grid.EditorGridPanel.superclass.initComponent.call(this);

        if(!this.selModel){
            this.selModel = new Ext.grid.CellSelectionModel();
        }

        this.activeEditor = null;

		    this.addEvents(
	            
	            "beforeedit",
	           
	            "afteredit",
	            
	            "validateedit",
	            
	            "formatedit"
	        );
    },
	 	// private
    onEditComplete : function(ed, value, startValue){
        this.editing = false;
        this.activeEditor = null;
        ed.un("specialkey", this.selModel.onEditorKey, this.selModel);
				var r = ed.record;
        var field = this.colModel.getDataIndex(ed.col);
        value = this.postEditValue(value, startValue, r, field);
        if(String(value) !== String(startValue)){
            var e = {
                grid: this,
                record: r,
                field: field,
                originalValue: startValue,
                value: value,
                row: ed.row,
                column: ed.col,
                cancel:false
            };
            if(this.fireEvent("validateedit", e) !== false && !e.cancel){
                r.set(field, e.value);
                delete e.cancel;
                //add event run
            		this.fireEvent("formatedit", e);
                this.fireEvent("afteredit", e);
            }
        }
        this.view.focusCell(ed.row, ed.col);
    }
});

Ext.apply(Ext.grid.GridPanel.prototype, {
	
	aliasAutoLoad : false,
	
	remoteSort : false,
	
	stripleColor : ' x-grid3-row-alt ',
	
	subSummaryText : "",

	summaryText : "",

	// 修正折叠显示时无数据的Bug
	onResize : function() {
		Ext.grid.GridPanel.superclass.onResize.apply(this,arguments);
		if(this.viewReady && this.view.innerHd.firstChild){this.view.updateHeaders();this.view.refresh();this.view.layout()}
	},
	
	dynaShow : function(options, params) {
		options = options || {};
		params = params || {};

		var oGrid = this;
		var oStore = this.getStore();
		var oReader = oStore.reader;
		var oColumnModel = this.getColumnModel();

		options.configUrl = options.configUrl || oStore.proxy.conn.url;

		var config = {};
		// \u8bbe\u7f6e\u9ed8\u8ba4\u503c
		config.start = options.start || 0;
		config.limit = options.limit || 10;
		config.url = options.configUrl;
		config.msgTitle = '\u8fdb\u5ea6\u6761';
		config.msgWaitMsg = '\u5904\u7406\u4e2d';
		config.msgProgressText = 'Initializing...';
		config.msgWidth = 300;

		// \u8986\u76d6\u7528\u6237\u81ea\u5b9a\u4e49\u8bbe\u7f6e
		Ext.apply(config, options);
		// \u8bbe\u7f6eparams\u53c2\u6570
		params.start = config.start;
		params.limit = config.limit;

		// \u8bbe\u7f6e\u8fdb\u5ea6\u6761
		var percentage = 0;
		Ext.MessageBox.show({
			title : config.msgTitle,
			msg : config.msgWaitMsg,
			progressText : config.msgProgressText,
			width : config.msgWidth,
			progress : true,
			closable : false
		});
		var progressTask = {
			/**
			 * @ignore
			 */
			run : function() {
				var progress = percentage / 100;
				if (progress >= 1) {
					progress = 1;
				}
				Ext.MessageBox.updateProgress(progress, (progress * 100) + "%");
				percentage = percentage + 10;
			},
			interval : 1000
				// 1 second
		}
		var taskRunner = new Ext.util.TaskRunner();
		taskRunner.start(progressTask);

		var o = {
			url : config.url,
			params : params,
			/**
			 * @ignore
			 */
			success : function(resp, opts) {
				oGrid.fireEvent('completeRequestMeta', this);
				
				taskRunner.stop(progressTask);
				Ext.MessageBox.hide();
				percentage = 0;
	
				var result = Ext.decode(resp.responseText);
	
				// \u6570\u636erecord\u662f\u4e00\u4e2aRecord\u7ed3\u6784\u7684\u6570\u7ec4
				var recordStructure = result.record;
				// \u6570\u636ecolModel\u662f\u4e00\u4e2aColumnModel\u7ed3\u6784\u7684\u6570\u7ec4
				var colModelStructure = result.colModel;
	
				if (recordStructure) {
					var array = new Array();
					for (var i=0; i<recordStructure.length; i++) {
						recordStructure[i].dyna = true;
					}
					oStore.fields.each(function(item){
						if (item.dyna == undefined) {
							array.push(item);
						} 
					});
					recordStructure = array.concat(recordStructure);
					recordStructure = Ext.data.Record.create(recordStructure);
					oReader.recordType = oStore.recordType = recordStructure;
					oStore.fields = oStore.recordType.prototype.fields;
				}
			
				var array = new Array();
				for (var i=0; i<colModelStructure.length; i++) {
					colModelStructure[i].dyna = true;
				}
				for (var i=0; i<oColumnModel.config.length; i++) {
					if (oColumnModel.config[i].dyna == undefined) {
						array.push(oColumnModel.config[i]);
					} 
				}
				colModelStructure = array.concat(colModelStructure);
				oColumnModel.setConfig(colModelStructure);
				
				oStore.on('beforeload', function(store, opts) {
					oReader.ef = false;
				});
				
				if (oGrid.aliasAutoLoad) {
					oStore.load({
						params : {
							start : config.start,
							limit : config.limit
						}
					});
				}
			},
			/**
			 * @ignore
			 */
			failure : function(resp, opts) {
				oGrid.fireEvent('errorRequestMeta', this);
			}
		}
		this.fireEvent('beforeRequestMeta', this);
		Ext.Ajax.request(o);
	},

	treeDynaShow : function(options, params) {
		options = options || {};
		params = params || {};

		var oGrid = this;
		var oStore = this.getStore();
		var oActionStore = this.getActionStore();
		var oReader = oActionStore.reader;
		var oColumnModel = this.getColumnModel();

		options.configUrl = options.configUrl || oActionStore.proxy.conn.url;

		var config = {};
		// \u8bbe\u7f6e\u9ed8\u8ba4\u503c
		config.start = options.start || 0;
		config.limit = options.limit || 10;
		config.url = options.configUrl;
		config.msgTitle = '\u8fdb\u5ea6\u6761';
		config.msgWaitMsg = '\u5904\u7406\u4e2d';
		config.msgProgressText = 'Initializing...';
		config.msgWidth = 300;

		// \u8986\u76d6\u7528\u6237\u81ea\u5b9a\u4e49\u8bbe\u7f6e
		Ext.apply(config, options);
		// \u8bbe\u7f6eparams\u53c2\u6570
		params.start = config.start;
		params.limit = config.limit;

		// \u8bbe\u7f6e\u8fdb\u5ea6\u6761
		var percentage = 0;
		Ext.MessageBox.show({
			title : config.msgTitle,
			msg : config.msgWaitMsg,
			progressText : config.msgProgressText,
			width : config.msgWidth,
			progress : true,
			closable : false
		});
		var progressTask = {
			/**
			 * @ignore
			 */
			run : function() {
				var progress = percentage / 100;
				if (progress >= 1) {
					progress = 1;
				}
				Ext.MessageBox.updateProgress(progress, (progress * 100) + "%");
				percentage = percentage + 10;
			},
			interval : 1000
				// 1 second
		}
		var taskRunner = new Ext.util.TaskRunner();
		taskRunner.start(progressTask);

		var o = {
			url : config.url,
			params : params,
			/**
			 * @ignore
			 */
			success : function(resp, opts) {
				oGrid.fireEvent('completeRequestMeta', this);
				
				taskRunner.stop(progressTask);
				Ext.MessageBox.hide();
				percentage = 0;
	
				var result = Ext.decode(resp.responseText);
	
				// \u6570\u636erecord\u662f\u4e00\u4e2aRecord\u7ed3\u6784\u7684\u6570\u7ec4
				var recordStructure = result.record;
				// \u6570\u636ecolModel\u662f\u4e00\u4e2aColumnModel\u7ed3\u6784\u7684\u6570\u7ec4
				var colModelStructure = result.colModel;
	
				if (recordStructure) {
					var array = new Array();
					for (var i=0; i<recordStructure.length; i++) {
						recordStructure[i].dyna = true;
					}
					oActionStore.fields.each(function(item){
						if (item.dyna == undefined) {
							array.push(item);
						} 
					});
					recordStructure = array.concat(recordStructure);
					recordStructure = Ext.data.Record.create(recordStructure);
					oReader.recordType = oActionStore.recordType = recordStructure;
					oActionStore.fields = oActionStore.recordType.prototype.fields;
				}
			
				var array = new Array();

				for (var i=0; i<colModelStructure.length; i++) {
					if (colModelStructure[i].editorType == 'check') {
						colModelStructure[i] = new Ext.grid.TreeCheckColumn(colModelStructure[i]);
						colModelStructure[i].init(oGrid);
					}
					colModelStructure[i].dyna = true;
				}
				for (var i=0; i<oColumnModel.config.length; i++) {
					if (oColumnModel.config[i].dyna == undefined) {
						array.push(oColumnModel.config[i]);
					} 
				}
				colModelStructure = array.concat(colModelStructure);
				oColumnModel.setConfig(colModelStructure);
				
				oActionStore.on('beforeload', function(store, opts) {
					oReader.ef = false;
				});
				if (oGrid.aliasAutoLoad) {
					oActionStore.load({
						params : {
							start : config.start,
							limit : config.limit
						},
						callback : function (rs) {
							oStore.removeAll();
							for(i=rs.length-1; i>-1; i--) {
								oStore.insert(0,rs[i]);
							}
						}
					});
				}
			},
			/**
			 * @ignore
			 */
			failure : function(resp, opts) {
				oGrid.fireEvent('errorRequestMeta', this);
			}
		}
		this.fireEvent('beforeRequestMeta', this);
		Ext.Ajax.request(o);
	}
});

/**
 *  Ext.grid.ColumnModel Override class definitions
 */
Ext.apply(Ext.grid.ColumnModel.prototype, {
    setConfig : function(config, initial){
        if(!initial){ // cleanup
            delete this.totalWidth;
            for(var i = 0, len = this.config.length; i < len; i++){
                var c = this.config[i];
                if(c.editor && c.dyna){
                    c.editor.destroy();
                }
            }
        }
        this.config = config;
        this.lookup = {};
        // if no id, create one
        for(var i = 0, len = config.length; i < len; i++){
            var c = config[i];
            if(typeof c.renderer == "string"){
                c.renderer = Ext.util.Format[c.renderer];
            }
            if(typeof c.id == "undefined"){
                c.id = i;
            }
            if(c.editor){
            	if(c.editorCfg == undefined) {
            		c.editorCfg = c.editor;
            	}
            	if(c.editorCfg.isFormField){
                	c.editor = new Ext.grid.GridEditor(c.editorCfg);
                }
            }
            this.lookup[c.id] = c;
        }
        if(!initial){
            this.fireEvent('configchange', this);
        }
    }
});

/*******************************************************************************
 * 表单工具方法
 *******************************************************************************/

//private
/**
 * @ignore
 * 表格部分
 */
Wonders.grid.completeHandler = function(response, options, op, errorMsg, successMsg) {
	var msg = Ext.decode(response.responseText);
	if (typeof(op) == 'undefined')
		op = '\u64cd\u4f5c';

	if ((typeof(msg) != 'undefined') && msg.success) {
		if(successMsg){
			Wonders.Msg.info(successMsg);
			return true;
		}else{
			Wonders.Msg.info(op + '\u6210\u529f\uff01');
			return true;
		}
	} else {
		if(errorMsg){
			Wonders.Msg.info(errorMsg);
			return false;
		}else{
			Wonders.Msg.warn(op + '\u5931\u8d25\uff01');
			return false;
		}
	}
}

/**
 * 验证表格
 * @class Wonders.grid.validateGrid
 * @param grid
 *            表格对象
 * 
 * @result 是否有效
 */
Wonders.grid.validateGrid = function(grid) {
	var store = grid.getStore();
	var colModel = grid.getColumnModel();
	var gridView = grid.getView();
	var gridMainBody = gridView.mainBody;
	var title;
	if (typeof(grid.title) != undefined) {
		title = '[' + grid.title + ']';
	}
	var m = store.getModifiedRecords();
	m.sort(function(oo1, oo2) {
		var row1 = store.data.indexOf(oo1);
		var row2 = store.data.indexOf(oo2);
		return row1 > row2;
	});
	for (var i = 0, len = m.length; i < len; i++) {
		// \u6570\u636e\u7ea6\u675f\u9a8c\u8bc1
		var row = store.data.indexOf(m[i]);
		for (var j = 0; j < colModel.getColumnCount(); j++) {
			// add:
			// \u6570\u636e\u7ea6\u675f\uff0c\u9884\u52a0\u8f7d\u7684\u9519\u8bef\u6570\u636e
			var columnId = colModel.getColumnId(j);
			var selectCell = gridMainBody.select('TD.x-grid3-td-' + columnId)
					.item(row);
			var exist = selectCell.hasClass('x-form-invalid');
			if (exist) {
				Wonders.Msg.info(title + '\u7b2c' + (row + 1) + '\u884c['
						+ colModel.getColumnHeader(j) + ']: '
						+ colModel.getCellEditor(j, row).field.invalidText);
				return false;
			}

			if (colModel.isCellEditable(j, row)) {
				colModel.getCellEditor(j, row).field
						.setValue(m[i].data[colModel.getDataIndex(j)]);
				if (!colModel.getCellEditor(j, row).field.validate()) {
					Wonders.Msg.info(title + '\u7b2c' + (row + 1) + '\u884c['
							+ colModel.getColumnHeader(j) + ']: '
							+ colModel.getCellEditor(j, row).field.invalidText);
					return false;
				}
			}
		}
	}
	return true;
}

// modify by xieguoking in 10-03-23
// gridid->grid;storeId->store

/**
 * 添加表格新行
 * @class Wonders.grid.addNewRow
 *
 * @param grid
 * 			表格对象
 * @param newRowData
 * 			新行数据
 * @param disallowBatch
 * 			禁止批量添加
 */
Wonders.grid.addNewRow = function(grid, newRowData, disallowBatch) {
	var store = grid.getStore();
	if (disallowBatch && store.getCount() > 0
			&& (store.find('isNew', true) != -1)) {
		Wonders.Msg
				.info('\u8bf7\u5148\u4fdd\u5b58\u5df2\u7f16\u8f91\u7684\u9879\u76ee!');
		return;
	}

	var colModel = grid.getColumnModel();
	var recordClass = store.getRecordClass();

	var record = new recordClass(newRowData);
	record.isNew = true;
	// add by xieguojun
	record.data.isNew = true;
	grid.stopEditing();
	store.insert(0, record);
	// added by likejun in 09_01_21
	store.getModifiedRecords().push(record);
	var len = colModel.getColumnCount();
	var col;
	for (var i = 0; i < len; i++) {
		if (colModel.isCellEditable(i, 0)) {
			col = i;
			break;
		}
	}
	grid.startEditing(0, col);
	grid.getView().refresh();
		// added by luzhong in 10_05_05
}

// modify by xieguoking in 10-03-23
// gridid->grid;storeId->store
/**
 * 添加表格数据
 * @class Wonders.grid.addRows
 *
 * @param grid
 * 			表格对象
 * @param dataArray
 * 			新行数据数组
 */
Wonders.grid.addRows = function(grid, dataArray) {
	var store = grid.getStore();
	for (var i = 0; i < dataArray.length; i++) {
		Wonders.grid.addNewRow(grid, store, dataArray[i]);
	}
}

// modify by xieguoking in 10-03-23
// gridid->grid;storeId->store
/**
 * 
 * 更新表格数据
 * @class Wonders.grid.updateGrid
 *
 * @param grid
 * 			表格对象
 * @param targetUrl
 * 			提交url
 * @param paramName
 * 			参数名称
 * @param dataIndex
 *          数据主键索引名
 * @param waitMsg
 *          等待信息
 * @param completeFunction
 *          提交成功后的操作
 * @param extraParams
 *          额外提交参数
 * @param reload
 *          是否提交后重新加载数据
 * @param validateFunction
 *          提交前验证的操作
 * @param errorRedirect
 *          是否提交失败后重定向到错误页面
 * @param paramhandleFunction
 *          提交前参数处理的操作
 * @param autoCommit
 *          是否自动提交更新到数据仓库
 * @param errorMsg
 *          提交失败后的提示信息
 * @param successMsg
 *          提交成功后的提示信息
 */
Wonders.grid.updateGrid = function(grid, targetUrl, paramName, dataIndex,
		waitMsg, completeFunction, extraParams, reload, validateFunction,
		errorRedirect, paramhandleFunction, autoCommit, errorMsg, successMsg) {

	if (typeof(reload) == 'undefined') {
		reload = true;
	}
	var store = grid.getStore();

	var colModel = grid.getColumnModel();
	/* add start */
	var gridView = grid.getView();
	var gridMainBody = gridView.mainBody;
	/* add end */
	var m = store.getModifiedRecords();
	var jsonData = "";
	var jsonDataOfDel = "";

	var isDelete = false;

	for (var i = 0, len = m.length; i < len; i++) {
		// \u6570\u636e\u7ea6\u675f\u9a8c\u8bc1
		var row = store.data.indexOf(m[i]);
		for (var j = 0; j < colModel.getColumnCount(); j++) {
			// add:
			// \u6570\u636e\u7ea6\u675f\uff0c\u9884\u52a0\u8f7d\u7684\u9519\u8bef\u6570\u636e
			var columnId = colModel.getColumnId(j);
			var selectCell = gridMainBody.select('TD.x-grid3-td-' + columnId)
					.item(i);
			var exist = false; // typeof(selectCell)=='undefined'?false:selectCell.hasClass('x-form-invalid');
			if (exist) {
				Wonders.Msg.info('\u7b2c' + (row + 1) + '\u884c['
						+ colModel.getColumnHeader(j) + ']: '
						+ colModel.getCellEditor(j, row).field.invalidText);
				return;
			}

			if (colModel.isCellEditable(j, row)) {
				colModel.getCellEditor(j, row).field
						.setValue(m[i].data[colModel.getDataIndex(j)]);
				if (!colModel.getCellEditor(j, row).field.validate()) {
					Wonders.Msg.info('\u7b2c' + (row + 1) + '\u884c['
							+ colModel.getColumnHeader(j) + ']: '
							+ colModel.getCellEditor(j, row).field.invalidText);
					return;
				}
			};
		}
		var ss = Ext.encode(m[i].data);
		if (paramhandleFunction) {
			ss = paramhandleFunction(row, m[i]);
		}

		if (typeof(m[i].data.isNew) != 'undefined'
				&& m[i].data.isNew == 'false')
			isDelete = true;
		else
			isDelete = false;

		// if (isDelete) {
		if(false) {
			if (jsonDataOfDel == "")
				jsonDataOfDel = jsonDataOfDel + ss;
			else
				jsonDataOfDel = jsonDataOfDel + "," + ss;
		} else {
			if (jsonData == "")
				jsonData = jsonData + ss;
			else
				jsonData = jsonData + "," + ss;
		}

	}
	if (jsonData == "" && jsonDataOfDel == "")
		return;
	// \u9a8c\u8bc1\u5f85\u63d0\u4ea4\u6570\u636e
	if (validateFunction) {
		if (!validateFunction(jsonData, m)) {
			return;
		}
	}
	var params = {};
	if (extraParams) {
		params = extraParams;
	}
	params[typeof(paramName) != undefined ? paramName : 'modifiedData'] = jsonData;
	params['deleteData'] = jsonDataOfDel;

	// chenweijie: showing progressbar as the client interact with the server
	if (typeof(waitMsg) != 'undefined') {
		var percentage = 0;
		Ext.MessageBox.show({
			title : '\u8fdb\u5ea6\u6761',
			msg : waitMsg,
			progressText : 'Initializing...',
			width : 300,
			progress : true,
			closable : false
		});
		var progressTask = {
			run : function() {
				var progress = percentage / 100;
				if (progress >= 1) {
					progress = 1;
				}
				Ext.MessageBox.updateProgress(progress, (progress * 100) + "%");
				percentage = percentage + 10;
			},
			interval : 1000
				// 1 second
		}
		var taskRunner = new Ext.util.TaskRunner();
		taskRunner.start(progressTask);
	}

	Ext.Ajax.request({
		url : targetUrl,
		params : params,
		waitMsg : (typeof(waitMsg) != undefined) ? waitMsg : 'Updating...',
		success : function(response, options) {
			if (typeof(waitMsg) != 'undefined') {
				taskRunner.stop(progressTask);
				Ext.MessageBox.hide();
				percentage = 0;
			}
			
			if (!Wonders.utils.complexHandleError(response.responseText, true,
					typeof(errorRedirect) != undefined ? errorRedirect : false)) {

				if (reload) {
					var result = Ext.decode(response.responseText);
					var fields = store.getRecordClass().prototype.fields;
					var fieldsName = [];

					if (typeof(dataIndex) == undefined) {
						dataIndex = 'id';
					}

					if (result.result) {
						var usedNums = [];
						// add by
						// xieguojun,\u7528\u4e8e\u8bbe\u7f6e\u8fd4\u56de\u7684\u4e3b\u952e\u503c
						var loop = 0;

						var ids = result.result[0]['ids'];
						for (var j = 0; j < m.length; j++) {
							if (typeof(m[j].data['isNew']) != 'undefined') {
								if (loop < ids.length) {
									m[j].set(dataIndex, ids[loop]['id']);
									delete m[loop].data.isNew;
									loop++;
								}
							}
						}
					}
				}
				// commet by
				// xieguojun,\u8fd9\u6bb5\u5185\u5bb9\u5728\u8bbe\u7f6e\u4e3b\u952e\u503c\u4e2d\u64cd\u4f5c\u8fc7
				/*
				 * for (var i = 0; i < m.length; i++) { if
				 * (typeof(m[i].data['isNew'] != 'undefined')) { delete
				 * m[i].data.isNew; } }
				 */

				var commited = false;
				if (completeFunction) {
					commited = completeFunction(response, options);
				} else {
					commited = Wonders.grid.completeHandler(response, options,
							'\u4fdd\u5b58\u6570\u636e', errorMsg, successMsg);
				}

				if ((typeof(autoCommit) == 'undefined' || autoCommit == true)
						&& commited) {
					store.commitChanges();
				}
				if (reload) {
					store.reload();
				}
				grid.getView().refresh();
			}
		}
	});
}

// modify by xieguoking in 10-03-23
// storeId->store
/**
 * 刷新表格数据
 * @class Wonders.grid.refreshGrid
 *
 * @param store
 * 			表格数据仓库
 * @param loadParams
 * 			加载参数
 */
Wonders.grid.refreshGrid = function(store, loadParams) {

	store.rejectChanges();
	store.load({
		params : loadParams
	});
}

// modify by xieguoking in 10-03-23
// storeId->store ,gridId->grid
/**
 * 删除表格数据
 * @class Wonders.grid.removeRows
 *
 * @param grid
 * 			表格对象
 * @param targetUrl
 * 			提交url
 * @param paramName
 * 			参数名称
 * @param dataIndex
 *          数据主键索引名
 * @param waitMsg
 *          等待信息
 * @param completeFunction
 *          提交成功后的操作
 * @param extraParams
 *          额外提交参数
 * @param errorRedirect
 *          是否提交失败后重定向到错误页面
 */
Wonders.grid.removeRows = function(grid, targetUrl, paramName, dataIndex,
		waitMsg, completeFunction, extraParams, errorRedirect) {

	var store = grid.getStore();
	var records = grid.getSelectionModel().getSelections();
	var len = records.length;

	if (len > 0) {
		Wonders.Msg.confirm(
				'\u786e\u5b9a\u8981\u5220\u9664\u8be5\u8bb0\u5f55\u5417?',
				'\u4fe1\u606f', doDel);
	} else {
		Wonders.Msg
				.info('\u8bf7\u9009\u62e9\u8981\u5220\u9664\u7684\u8bb0\u5f55');
	}

	function doDel(btn, text) {
		if (!dataIndex) {
			dataIndex = 'id';
		}
		var len = records.length;
		if (btn == 'yes') {
			var jsonData = "";
			for (var i = 0; i < len; i++) {
				var recordObj = records[i];
				var recordId = recordObj.data[dataIndex];
				// \u6839\u636e \u552f\u4e00\u5217
				// \u6570\u636e\u4e0d\u4e3a\u7a7a\uff0c\u8868\u793a\u6570\u636e\u5df2\u7ecf\u56fa\u5316\u8fc7\uff0c\u90a3\u4e48\u9700\u8981\u63d0\u4ea4\u5220\u9664\uff0c\u8c22\u56fd\u94a7
				if ((typeof(recordId) != 'undefined') && (recordId != 0)
						&& (recordId != '')) {
					var recordClass = store.getRecordClass();
					var record = new recordClass({});

					record.data.isNew = 'false';
					record.data[dataIndex] = recordId;

					store.getModifiedRecords().push(record);
					store.remove(records[i]);
				} else {
					// \u6570\u636e \u552f\u4e00\u5217
					// \u4e3a\u7a7a\uff0c\u8868\u793a\u662f\u65b0\u589e\u7684\u6570\u636e\uff0c\u4e0d\u9700\u8981\u63d0\u4ea4\uff0c\u53ea\u9700\u8981\u5728modified\u4e2d\u5220\u9664\uff0c\u8c22\u56fd\u94a7
					store.getModifiedRecords().remove(recordObj);
					store.remove(recordObj);
				}
			}
			grid.getView().refresh();
		}
	}
};
// modify by xieguoking in 10-03-23
// storeId->store ,gridId->grid
/**
 * 删除表格数据
 * @class Wonders.grid.deleteRows
 *
 * @param grid
 * 			表格对象
 * @param targetUrl
 * 			提交url
 * @param paramName
 * 			参数名称
 * @param dataIndex
 *          数据主键索引名
 * @param waitMsg
 *          等待信息
 * @param completeFunction
 *          提交成功后的操作
 * @param extraParams
 *          额外提交参数
 * @param errorRedirect
 *          是否提交失败后重定向到错误页面
 * @param errorMsg
 *          提交失败后的提示信息
 * @param successMsg
 *          提交成功后的提示信息
 */
Wonders.grid.deleteRows = function(grid, targetUrl, paramName, dataIndex,
		waitMsg, completeFunction, extraParams, errorRedirect, errorMsg, successMsg) {
	var store = grid.getStore();
	var records = grid.getSelectionModel().getSelections();
	var len = records.length;

	if (len > 0) {
		Wonders.Msg.confirm(
				'\u786e\u5b9a\u8981\u5220\u9664\u8be5\u8bb0\u5f55\u5417?',
				'\u4fe1\u606f', doDel);
	} else {
		Wonders.Msg
				.info('\u8bf7\u9009\u62e9\u8981\u5220\u9664\u7684\u8bb0\u5f55');
	}

	function doDel(btn, text) {
		if (!dataIndex) {
			dataIndex = 'id';
		}
		var len = records.length;
		if (btn == 'yes') {
			var jsonData = "";
			for (var i=len-1; i >=0; i--) {
				var recordObj = records[i];
				var recordId = recordObj.data[dataIndex];
				// \u6839\u636e \u552f\u4e00\u5217
				// \u6570\u636e\u4e0d\u4e3a\u7a7a\uff0c\u8868\u793a\u6570\u636e\u5df2\u7ecf\u56fa\u5316\u8fc7\uff0c\u90a3\u4e48\u9700\u8981\u63d0\u4ea4\u5220\u9664\uff0c\u8c22\u56fd\u94a7
				if ((typeof(recordId) != 'undefined') && (recordId != 0)
						&& (recordId != '')) {
					var removeData = "";
					if(typeof(recordId) == 'string'){
						removeData = "{" + dataIndex + ": '" + recordId + "'}";
					}
					else{
						removeData = "{" + dataIndex + ": " + recordId + "}";
					}
					jsonData += (jsonData != "" ? "," : "") + removeData;
				} else {
					// \u6570\u636e \u552f\u4e00\u5217
					// \u4e3a\u7a7a\uff0c\u8868\u793a\u662f\u65b0\u589e\u7684\u6570\u636e\uff0c\u4e0d\u9700\u8981\u63d0\u4ea4\uff0c\u53ea\u9700\u8981\u5728modified\u4e2d\u5220\u9664\uff0c\u8c22\u56fd\u94a7
					store.getModifiedRecords().remove(recordObj);
					store.remove(recordObj);
					records.splice(i, 1);
				}
			}
			// \u672c\u5730\u5220\u9664\u672a\u63d0\u4ea4\u7684\u884c\u6570\u636e
			if (jsonData == "") {
				grid.getView().refresh();
				return;
			}
			var params = {};
			if (extraParams) {
				params = extraParams;
			}
			params[typeof(paramName) != undefined ? paramName : 'deleteData'] = jsonData;

			// chenweijie: showing progressbar as the client interact with the
			// server
			if (typeof(waitMsg) != 'undefined') {
				var percentage = 0;
				Ext.MessageBox.show({
					title : '\u8fdb\u5ea6\u6761',
					msg : waitMsg,
					progressText : 'Initializing...',
					width : 300,
					progress : true,
					closable : false
				});
				var progressTask = {
					run : function() {
						var progress = percentage / 100;
						if (progress >= 1) {
							progress = 1;
						}
						Ext.MessageBox.updateProgress(progress,
								(progress * 100) + "%");
						percentage = percentage + 10;
					},
					interval : 1000
						// 1 second
				}
				var taskRunner = new Ext.util.TaskRunner();
				taskRunner.start(progressTask);
			}

			Ext.Ajax.request({
				url : targetUrl,
				params : params,
				waitMsg : (typeof(waitMsg) != undefined)
						? waitMsg
						: 'Deleting...',
				success : function(response, options) {
					if (typeof(waitMsg) != 'undefined') {
						taskRunner.stop(progressTask);
						Ext.MessageBox.hide();
						percentage = 0;
					}
					if (!Wonders.utils.complexHandleError(
							response.responseText, true,
							typeof(errorRedirect) != undefined
									? errorRedirect
									: false)) {

						var commited = false;
						// CIN-884 LuZhong \u5148\u5220\u9664\u518d\u505a\u76f8\u5e94\u7684\u540e\u7eed\u64cd\u4f5c
						if(completeFunction){
							var msg = Ext.decode(response.responseText);
							if ((typeof(msg) != 'undefined') && msg.success) {
								for (var i = 0, len = records.length; i < len; i++) {
									store.remove(records[i]);
								}
							}
						}
							
						if (completeFunction) {
							 completeFunction(response, options);
						} else {
							 commited = Wonders.grid.completeHandler(response,
									options, '删除数据', errorMsg, successMsg);
						}
						if(commited != false){
							for (var i = 0, len = records.length; i < len; i++) {
								store.remove(records[i]);
							}
							store.reload();
						}
					}
					grid.getView().refresh();
				}
			});

		}
	}
};

/**
 * 供表格和表单统一提交时重新加载数据仓库
 * @class Wonders.grid.reloadGrid
 *
 * @param grid
 * 			表格对象
 * @param reload
 * 			是否重新加载
 * @param result
 * 			结果集JSON对象
 */
Wonders.grid.reloadGrid = function(grid, reload, result) {
	var store = grid.getStore();
	var m = store.getModifiedRecords();
	if (reload) {
		var fields = store.getRecordClass().prototype.fields;
		var fieldsName = [];
		for (var i = 0; i < fields.getCount(); i++) {
			var propName = fields.getKey(fields.get(i));
			fieldsName.push(propName);
		}

		var gridResult;
		var results = result.result;
		
		if (results == undefined){
			store.commitChanges();
			return;
		}

		for (var gri = 0; gri < results.length; ++gri) {
			var prop = grid.property + "ids";
			if (prop in results[gri]) {
				gridResult = results[gri][prop];
				break;
			}
		}

		if (gridResult) {
			var usedNums = [];
			var loop = 0;
			for (var j = 0; j < m.length; j++) {
				if (typeof(m[j].data['isNew']) != 'undefined') {
					if (loop < gridResult.length) {
						for (var k = 0; k < fieldsName.length; ++k) {
							if (typeof(gridResult[loop][fieldsName[k]]) != 'undefined')
								m[j].set(fieldsName[k],
										gridResult[loop][fieldsName[k]]);
						}
						delete m[loop].data.isNew;
						loop++;
					}
				}
			}
		}
	}

	store.commitChanges();
}

/**
 * 供表格和表单统一提交时重新加载数据仓库
 * @class Wonders.grid.reloadStore
 *
 * @param store
 * 			表格数据仓库
 * @param reload
 * 			是否重新加载
 * @param result
 * 			结果集JSON对象
 */
Wonders.grid.reloadStore = function(store, reload, result) {
	var m = store.getModifiedRecords();
	if (reload) {
		var fields = store.getRecordClass().prototype.fields;
		var fieldsName = [];
		for (var i = 0; i < fields.getCount(); i++) {
			var propName = fields.getKey(fields.get(i));
			fieldsName.push(propName);
		}
		if (result.result) {
			var loop = 0;
			var usedNums = [];
			for (var i = 0; i < result.result.length; i++) {
				for (var j = 0; j < m.length; j++) {
					for (var k = 0; k < fieldsName.length; ++k) {
						if (typeof(result.result[loop][fieldsName[k]]) != 'undefined')
							m[j].set(fieldsName[k],
									result.result[loop][fieldsName[k]]);
					}
					delete m[loop].data.isNew;
					loop++;
				}
			}
		}
	}
	for (var i = 0; i < m.length; i++) {
		if (typeof(m[i].data['isNew'] != 'undefined')) {
			delete m[i].data.isNew;
		}
	}
	store.commitChanges();
}

/**
 * 复合错误信息处理函数,用于包含表格的后台异常信息和验证信息的展现
 * @class Wonders.utils.complexHandleError
 *
 * @param jsonData
 *            JSON格式数据
 * @param markInvalid
 *            是否为Field标记错误信息
 * @param redirect
 *            当JSON数据中包含转向页面地址时，是否页面转向
 */
Wonders.utils.complexHandleError = function(jsonData, markInvalid, redirect) {
	var obj = Ext.decode(jsonData);
	if (obj.errors && obj.errors.length > 0) {
		for (i = 0; i < obj.errors.length; i++) {
			if (obj.errors[i].id && obj.errors[i].id != "") {
				if (markInvalid) {
					var collection = Ext.ComponentMgr.all.filter('name',
							obj.errors[i].id);
					if (collection != null) {
						for (var j = 0; j < collection.getCount(); j++) {
							if (typeof(collection.get(j).markInvalid) == "function") {
								collection.get(j)
										.markInvalid(obj.errors[i].msg);
							}
						}
					}
				} else {
					window.alert(obj.errors[i].msg);
				}
			}
			// \u8868\u683c
			else {
				var collection = Ext.ComponentMgr.all;
				if (collection != null) {
					for (var j = 0; j < collection.getCount(); j++) {
						var component = collection.get(j);
						if (typeof(component.getXTypes) != "function"
								|| component.getXTypes().indexOf('grid') < 0
								|| typeof(component.getStore) != "function") {
							continue;
						}
						var title;
						if (typeof(component.title) != undefined) {
							title = '[' + component.title + ']';
						}
						var row = obj.errors[i].row;
						if (row != null && row > -1) {
							var isExist = false;
							if (obj.errors[i].dataIndex) {
								var colModel = component.getColumnModel();
								for (var k = 0; k < colModel.getColumnCount(); k++) {
									if (obj.errors[i].dataIndex == colModel
											.getDataIndex(k)) {
										isExist = true;
										var cell = component.getView().mainBody
												.select('TD.x-grid3-td-'
														+ colModel
																.getColumnId(k))
												.item(row);
										cell.addClass('x-form-invalid');
										cell.dom.title = obj.errors[i].msg;
										break;
									}
								}
							}
							if (!isExist) {
								window.alert(title + '\u7b2c' + (row + 1)
										+ '\u884c: ' + obj.errors[i].msg);
							}
						} else {
							window.alert(title + ":" + obj.errors[i].msg);
						}
					}
				}
			}
		}
	} else {
		return false;
	}
	if (obj.target && redirect) {
		window.top.location = obj.target;
	}
	return true;
}

/**
 * @ignore
 */
Wonders.grid.toHtmlA = function(v, f, t) {
	var params = 'id=' + v;
	return '<a href="#" onclick="' + f + '(\'\',\'' + params + '\')">' + t
			+ '</a>';
}

/**
 * @ignore
 */
Wonders.grid.toHtmlB = function(v, f, t) {
	var params = 'id=' + v;
	return '<input type="button" onclick="' + f + '(\'\',\'' + params
			+ '\')" value="' + t + '"/>';
}

/**
 * @ignore 
 * 格式化日期时间 
 */
Wonders.grid.formatDate = function(v, f) {
	return v ? v.dateFormat(f) : '';
}

/**
 * @ignore 
 * 格式化整形
 */
Wonders.grid.formatInt = function(v, f) {
	return v;
}

 /**
  * 格式化浮点数
  *  @param value
  *  	数值
  *  @param format
  *  	格式：d-p-s(d=小数点后位数,p=前缀,s=后缀)
  *     示例:(2000.2142,'2-$-Y')---->$2000.21Y
  * @ignore
  */
 Wonders.grid.formatNumber = function(v, f) {
 	if(f.length==0 || isNaN(v) || !isFinite(v)){
 		return v;
 	}
    var fmt=f.split('-');
 	var len=fmt.length;
 	if(len>0){
 		//小数点后位数
 		var digits=parseInt(fmt[0]);
 		if(digits>=0){
 			//v=Number(v).toFixed(digits);
 			v=""+Math.round(v*Math.pow(10,digits))/Math.pow(10,digits);
 			var ps = v.split('.');//整数+小数点+小数部分
 			//整数部分格式化,逢3添分隔符
 			var r = /(\d+)(\d{3})/;
 		    while (r.test(ps[0])) {
 		        ps[0] = ps[0].replace(r, '$1' + ',' + '$2');
 		    }
 		   //传递整数,从而整除,则缺少小数点,或者位数不够,则手动添加
		    ps[1]==undefined ? ps[1]="":null;
		    var wrap=digits-ps[1].length;
		    while(wrap--){
		    	ps[1]+="0";
		    } 
		    digits>0 ? v=ps.join("."):null;
 		}
 	}
 	//前缀
 	len>1 ? v=fmt[1]+v:null;
 	//后缀
 	len>2 ? v=v+fmt[2]:null;
 	return v;
 }

/**
 * @ignore
 */
Wonders.grid.addQtip = function(v, m, r, p) {
	var qtipTpl = new Ext.XTemplate(  
					    '<tpl for=".">',    
					    '<div>{' + p + '}</div>',    
					    '</tpl>'    
							);  
  var data = r.data;
  var qtip = qtipTpl.apply(data);  
  m.attr =  ' ext:qtip="' + qtip + '"';
  return v;
}

/**
 * 复制选中表格行到剪贴板
 * @class Wonders.grid.copyColumn
 *
 * @param grid
 * 			表格对象
 */
Wonders.grid.copyColumn = function(grid) {

	var content = "";

	var colModel = grid.getColumnModel();
	var colCount = colModel.getColumnCount();
	var store = grid.getStore();

	var records = grid.getSelectionModel().getSelections();
	var len = records.length;

	var columns = grid.getView().getColumnData();

	var columnData = grid.getView().getColumnData();

	var showColumnData = [];

	// \u663e\u793a\u7684\u884c\u53f7\u6570\u7ec4
	var showColModel = new Array();

	for (var i = 0; i < colCount; i++) {
		if (typeof(colModel.config[i].hidden) != 'undefined'
				&& colModel.config[i].hidden === false) {
			showColModel.push(colModel.config[i].dataIndex);
			showColumnData.push(columnData[i]);
		}
	}

	var propValue;
	var propName;
	var r;
	var rowIndex;
	var p = {};
	var c;
	for (var k = 0; k < len; ++k) {
		// \u591a\u884c\u7684\u8bdd\uff0c\u8fdb\u884c\u6362\u884c
		if (k > 0)
			content += "\n";
		for (var i = 0; i < showColModel.length; i++) {
			r = records[k];
			rowIndex = store.indexOf(r);

			c = showColumnData[i];

			propName = showColModel[i];

			p.attr = p.cellAttr = "";

			propValue = r.data[propName];
			if (c.dicBind) {
				propValue = Wonders.grid.transformDicData(propValue, c.dicBind);
			}
			propValue = c.renderer(propValue, p, r, rowIndex, i, store);

			content += " " + propValue;
		}
	}
	if (Wonders.grid.copyToClipboard(content))
		Ext.Msg.alert('\u63d0\u793a',
				'\u62f7\u8d1d\u5185\u5bb9\u6210\u529f\uff01');
	else
		Ext.Msg
				.alert(
						'\u8b66\u544a',
						'\u5f53\u524d\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u590d\u5236\u529f\u80fd\uff01');

}

/**
 * @ignore
 * 数据转换, Gaoshang
 */
Wonders.grid.transformDicData = function(v, dicData) {
	if (dicData instanceof Array) {
		for (var i = 0; i < dicData.length; i++) {
			if (dicData[i] instanceof Array && dicData[i].length > 1) {
				if (v == dicData[i][0]) {
					return dicData[i][1];
				}
			} else if (dicData[i] instanceof Object) {
				for (var key in dicData[i]) {
					if (key == v) {
						return dicData[i][key];
					}
				}
			}
		}
	}
	return v;
}

/**
 * 复制文本到剪贴板
 * @class Wonders.grid.copyToClipboard
 *
 * @param txt
 * 			文本
 */
Wonders.grid.copyToClipboard = function(txt) {
	if (window.clipboardData) {
		window.clipboardData.clearData();
		window.clipboardData.setData("Text", txt);
		return true;
	} else if (navigator.userAgent.indexOf("Opera") != -1) {
		window.location = txt;
		return true;
	} else if (window.netscape) {
		try {
			netscape.security.PrivilegeManager
					.enablePrivilege("UniversalXPConnect");
		} catch (e) {
			alert("\u88ab\u6d4f\u89c8\u5668\u62d2\u7edd\uff01\n\u8bf7\u5728\u6d4f\u89c8\u5668\u5730\u5740\u680f\u8f93\u5165'about:config'\u5e76\u56de\u8f66\n\u7136\u540e\u5c06'signed.applets.codebase_principal_support'\u8bbe\u7f6e\u4e3a'true'");
		}
		var clip = Components.classes['@mozilla.org/widget/clipboard;1']
				.createInstance(Components.interfaces.nsIClipboard);
		if (!clip)
			return false;
		var trans = Components.classes['@mozilla.org/widget/transferable;1']
				.createInstance(Components.interfaces.nsITransferable);
		if (!trans)
			return false;
		trans.addDataFlavor('text/unicode');
		var str = new Object();
		var len = new Object();
		var str = Components.classes["@mozilla.org/supports-string;1"]
				.createInstance(Components.interfaces.nsISupportsString);
		var copytext = txt;
		str.data = copytext;
		trans.setTransferData("text/unicode", str, copytext.length * 2);
		var clipid = Components.interfaces.nsIClipboard;

		if (!clip)
			return false;
		clip.setData(trans, null, clipid.kGlobalClipboard);

		return true;
	}
}

/**
 * @ignore
 * 创建json数据 * grid: *
 * flag:=delete表示创建删除数据的json
 * 否则为新增和修改的
 */
Wonders.grid.createJsonData = function(grid) {
	var store = grid.getStore();
	var colModel = grid.getColumnModel();
	/* add start */
	var gridView = grid.getView();
	var gridMainBody = gridView.mainBody;
	/* add end */
	var m = store.getModifiedRecords();
	var jsonData = "";
	var jsonDataOfDel = "";
	var json = [];
	for (var i = 0, len = m.length; i < len; i++) {
		var ss = Ext.encode(m[i].data);
		// if (typeof(m[i].data.isNew) != 'undefined'
		// 		&& m[i].data.isNew == 'false') {
		if(false) {
			if (jsonDataOfDel == "")
				jsonDataOfDel = jsonDataOfDel + ss;
			else
				jsonDataOfDel = jsonDataOfDel + "," + ss;
		} else {
			if (jsonData == "")
				jsonData = jsonData + ss;
			else
				jsonData = jsonData + "," + ss;

		}
	}

	json.push(jsonData);
	json.push(jsonDataOfDel);

	return json;
}

/**
 * @ignore
 */
Wonders.grid.createParams = function(paramName, jsonData, extraParams) {
	var params = {};
	if (extraParams) {
		params = extraParams;
	}
	params[typeof(paramName) != 'undefined' ? paramName : 'update'] = jsonData;
	return params;
}


/**
 * 表格查询
 * @class Wonders.grid.doQuery
 *
 * @param formId
 * 			查询条件所在表单的id 
 * @param gridId
 * 			表格id
 * @param loadexception
 * 			查询失败后的回调函数
 */
Wonders.grid.doQuery = function(formId, gridId, loadexception) {
   
	var form = Ext.getCmp(formId).getForm();
	var grid = Ext.getCmp(gridId);
	var values = form.getValues();
	//filter emptyText
	for (var param in values) {   
		if (form.findField(param)   
		&& form.findField(param).emptyText == values[param]) {   
			values[param]='';   
		}   
	}  
	
	if (grid.getColumnModel().getColumnById('rowNumber')!=null){
		grid.getColumnModel().getColumnById('rowNumber').start =0;
	}

	values.limit = grid.getStore().baseParams.limit;
	grid.getStore().baseParams = values;
	if(typeof(loadexception) =="function" ){
        grid.getStore().on('loadexception',loadexception);
    }
	
	grid.getStore().load({
		start : 0
	});
}

/**
 * @ignore
 * 删除array中值为v的数据，一次可删除多个
 * 谢国钧
 */
function removeArray(array, v) {
	if (array instanceof Array) {
		var loop = 0;
		for (var i = 0; i < array.length; i++) {
			if (array[i] != v) {
				array[loop++] = array[i];
			}
		}
		array.length -= array.length - loop;
	}
}
/**
 * @ignore
 * 注册remove到Array 
 * 谢国钧
 */
Array.prototype.remove = function(value) {
	return removeArray(this, value);
}

/**
 * @ignore
 * 校验v是否为空，为空进行提示
 * 使用地方：grid
 * store加载前，用于校验store.url是否为空
 */
Wonders.grid.checkNull = function(v, msg) {
	if (typeof(v) == 'undefined' || !v) {
		Wonders.Msg.info(msg, '\u8b66\u544a');
		// Wonders.Msg.warn (info,title)
		// Wonders.Msg.error (info,title)
		// Wonders.Msg.info (info,title)
		return true;
	}

	return false;
}

/**
 * @ignore
 * 渲染索引号
 * 使用地方：grid
 */
Wonders.grid.rownumberRender = function(value, rowIndex, ds, column) {
	return column.start + 1 + rowIndex;
}

/**
 * @ignore
 * 自适应的grid列按照百分比分配宽度
 * gridId 表格的id
 */
Wonders.grid.percentColumn = function(gridId){
	var grid = Ext.getCmp(gridId);
    var columnModel = grid.getColumnModel();
    var count = columnModel.getColumnCount();
    for (i=0;i<count;i++){
        var column = columnModel.getColumnById(columnModel.getColumnId(i));
        if (column.tempWidth!=null && column.tempWidth.indexOf('%') >= 0){
            var percent = parseInt(column.tempWidth.substr(0,column.tempWidth.length-1));
            columnModel.setColumnWidth(i, grid.getSize(false).width*percent/100);
        }else if (column.tempWidth!=null){
        	columnModel.setColumnWidth(i, parseInt(column.tempWidth));
        }
    }
    if (grid.getView().forceFit) { 
    	grid.getView().fitColumns(false, false);
    }
}

Wonders.grid.columnFlag = false;
Wonders.grid.columnTotalWidth = 0;
Wonders.grid.columnIndexWidths = [];
/**
 * @ignore
 * 因grid列的显隐来维持列总宽度不变
 * model 列模型 index 显隐的列索引 hidden
 * 该列的显隐状态
 */
Wonders.grid.keepColumnWidth = function(model,index,hidden){    
    var indexes = [];
    var totalShowWidth = 0;
    if (!Wonders.grid.columnFlag){
        for (i=0;i<model.getColumnCount();i++){
            Wonders.grid.columnIndexWidths.push(model.getColumnWidth(i));
	        if ((model.getDataIndex(i)!='' && !model.isHidden(i)) || i==index){
	            Wonders.grid.columnTotalWidth += model.getColumnWidth(i);
	        }
        }
        Wonders.grid.columnFlag = true;
        
        if (!hidden){
            Wonders.grid.columnTotalWidth -= model.getColumnWidth(index);
        }
    }
    
    for (i=0;i<model.getColumnCount();i++){
        if (!model.isHidden(i) && model.getDataIndex(i)!=''){
            indexes.push(i);
            totalShowWidth += Wonders.grid.columnIndexWidths[i];
        }
    }
    
    for (var j=0;j<indexes.length;j++){
        model.setColumnWidth(indexes[j], Wonders.grid.columnIndexWidths[indexes[j]]* Wonders.grid.columnTotalWidth / totalShowWidth);
    }
}

/**
 * @ignore
 * 树形表格
 */
Wonders.grid.TreeGridViewUtils = {};


/**
 * @ignore
 * find record with specified id
 * 
 */
Wonders.grid.TreeGridViewUtils.getRecord = function(store, targetId){
	for(var i=0 ;i < store.data.getCount(); i++){
		var record = store.data.itemAt(i);
		if(record.get('id')==targetId){
			return record;
		}
	}
	return null;
}

/**
 * @ignore
 * change status when tree node trigged
 * 
 */
Wonders.grid.TreeGridViewUtils.changeStatus = function(id, level, gridId) {
	var nodeEl = Ext.get('node-' + id);
	var iconEl = nodeEl.child("img.x-tree-ec-icon");
	if(nodeEl.hasClass('x-tree-node-loading')){
		return;
	}
	var grid = Ext.getCmp(gridId);
	var statusMap = grid.getView().getStatusMap();
	var childrenMap = grid.getView().getChildrenMap();
	var store = grid.getStore();
	// need Grid instance provide getActionStore method
	var ds = grid.getActionStore();
	var rowIndex = grid.getView().findRowIndex(nodeEl.dom);

	var parentNode = Wonders.grid.TreeGridViewUtils.getRecord(store, id);
	var status = statusMap.key(id);
	if (!status || status.collapsed) {
		nodeEl.addClass('x-tree-node-loading');
		// count++;
		ds.load({
			params:parentNode.data,
			callback : function(rs) {
				var childs = new Array;
				for (i = rs.length-1; i > -1; i--) {
					// rs[i].data.id += count * 100;
					childs.push(rs[i]);
					rs[i].data.level = level + 1;
					store.insert(rowIndex + 1, rs[i]);
					if (childrenMap != null && parentNode != null) {
						childrenMap.add(rs[i].data.id, parentNode);

					}
				}
				if (statusMap != null) {
					statusMap.add(id, {
						collapsed : false,
						childs : childs
					});
				}
				if (nodeEl) {
					nodeEl.removeClass('x-tree-node-loading');
					nodeEl.replaceClass("x-tree-node-collapsed",
							"x-tree-node-expanded");
				}
				if (iconEl) {
					iconEl.replaceClass("x-tree-elbow-plus",
							"x-tree-elbow-minus");
				}
			}
		});
	} else if (!status.collapsed) {
		Wonders.grid.TreeGridViewUtils.removeNodes(id, store, grid.getView());
		if (nodeEl) {
			nodeEl
					.replaceClass("x-tree-node-expanded",
							"x-tree-node-collapsed");
		}
		if (iconEl) {
			iconEl.replaceClass("x-tree-elbow-minus", "x-tree-elbow-plus");
		}
	}
}
/**
 * @ignore
 * remove the child nodes for the node with specified id
 */
Wonders.grid.TreeGridViewUtils.removeNodes = function (id, store, view) {
	var status = view.getStatusMap().key(id);
	if (status != null && !status.collapsed) {
		for (var i = 0; i < status.childs.length; i++) {
			var key = status.childs[i].data.id
			Wonders.grid.TreeGridViewUtils.removeNodes(key, store, view);
			view.getChildrenMap().removeKey(key);
			store.remove(status.childs[i]);
		}
		view.getStatusMap().add(id, {
			collapsed : true
		});	
	}

}

/**
 * @ignore
 */
Wonders.grid.TreeGridView = function(config){
	Ext.apply(this, config)
    this.statusMap = new Ext.util.MixedCollection();
	this.childrenMap = new Ext.util.MixedCollection();
    Wonders.grid.TreeGridView.superclass.constructor.call(this);
    this.addEvents("headerrender");
};

/**
 * TreeView Class need to provide renderColName attribute
 */
Ext.extend(Wonders.grid.TreeGridView, Ext.grid.GridView, {

	initTemplates : function() {
		Wonders.grid.TreeGridView.superclass.initTemplates.call(this);
		if (!this.treeNodeContent) {
			this.treeNodeContent = new Ext.XTemplate(
					'<div id="node-{dataId}" class="x-tree-node-el x-unselectable x-tree-node {nodeCss}" style="height:14px">',
					'<span class="x-tree-node-indent">{spaceImg}</span>',
					'<img class="x-tree-ec-icon {leafCss}" src=' + Ext.BLANK_IMAGE_URL + ' onclick="Wonders.grid.TreeGridViewUtils.changeStatus(\'{dataId}\',{currentLevel},\''
							+ this.grid.getId() + '\')" style="height:14px" />',
					'<img class="x-tree-node-icon" unselectable="on" src=' + Ext.BLANK_IMAGE_URL + ' style="height:14px" />',
					'<a href="#" hidefocus="on">',
					'<span unselectable="on">{value}</span>', '</a>', '</div>');
		}
		this.treeNodeContent.compile();
	},
	
	getStatusMap : function(){
		return this.statusMap;
	},
	
	getChildrenMap : function(){
		return this.childrenMap;
	},
	
	getTreeNodeHtml : function(value, r) {
		var level = r.data.level;
		if (level == null || isNaN(level)) {
			level = 0;
		}
		var spaceImg = "";
		for (var j = 0; j < level; j++) {
			spaceImg += '<img class="x-tree-elbow-line" src=' + Ext.BLANK_IMAGE_URL + ' style="height:14px"/>';
		}

		var tplValue = {
			dataId : r.data.id,
			spaceImg : spaceImg,
			currentLevel : level,
			value : value,
			leafCss:r.data.leaf ? "x-tree-elbow-minus" : "x-tree-elbow-plus",
			nodeCss: this.nodeCss == undefined ? "x-tree-no-lines x-tree-node-collapsed" : this.nodeCss
		}
		return this.treeNodeContent.apply(tplValue);
	},
	
	/**
	 * Override, disable the sort function
	 */ 
	onHeaderClick : function(g, index){},
    
	renderHeaders : function(){
	    var cm = this.cm, ts = this.templates;
        var ct = ts.hcell;

        var cb = [], sb = [], p = {};

        for(var i = 0, len = cm.getColumnCount(); i < len; i++){
            p.id = cm.getColumnId(i);
            p.value = cm.getColumnHeader(i) || "";
            p.style = this.getColumnStyle(i, true);
            if(cm.config[i].align == 'right'){
                p.istyle = 'padding-right:16px';
            }
            this.fireEvent("headerrender", this, p, i);
            cb[cb.length] = ct.apply(p);
        }
        return ts.header.apply({cells: cb.join(""), tstyle:'width:'+this.getTotalWidth()+';'});
	},
	
	
	/**
	 * Override, maintain the node status in update action
	 */
	refreshRow : function(record) {
		Wonders.grid.TreeGridView.superclass.refreshRow.call(this, record);
		var id = record.data.id;
		var status = this.getStatusMap().key(id);

		var nodeEl = Ext.fly(Ext.get('node-' + id));
		var iconEl = nodeEl.child("img.x-tree-ec-icon");
		if (nodeEl && iconEl && status) {
			if (!status.collapsed) {
				nodeEl.replaceClass("x-tree-node-collapsed",
						"x-tree-node-expanded");
				iconEl.replaceClass("x-tree-elbow-plus", "x-tree-elbow-minus");
			} else {
				nodeEl.replaceClass("x-tree-node-expanded",
						"x-tree-node-collapsed");
				iconEl.replaceClass("x-tree-elbow-minus", "x-tree-elbow-plus");

			}
		}
	},
	doRender : function(cs, rs, ds, startRow, colCount, stripe) {
		var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount - 1;
		var tstyle = 'width:' + this.getTotalWidth() + ';';
		var buf = [], cb, c, p = {}, rp = {
			tstyle : tstyle
		}, r;
		for (var j = 0, len = rs.length; j < len; j++) {
			r = rs[j];
			cb = [];
			var rowIndex = (j + startRow);
			for (var i = 0; i < colCount; i++) {
				c = cs[i];
				p.id = c.id;
				p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last
						? 'x-grid3-cell-last '
						: '');
				p.attr = p.cellAttr = "";

				if (c.name == this.renderColName) {
					p.value = this.getTreeNodeHtml(c.renderer(r.data[c.name],
							p, r, rowIndex, i, ds), r);
				} else {
					p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
				}

				p.style = c.style;
				if (p.value == undefined || p.value === "")
					p.value = "&#160;";
				if (r.dirty && typeof r.modified[c.name] !== 'undefined') {
					p.css += ' x-grid3-dirty-cell';
				}
				cb[cb.length] = ct.apply(p);
			}
			var alt = [];
			if (stripe && ((rowIndex + 1) % 2 == 0)) {
				alt[0] = "x-grid3-row-alt";
			}
			if (r.dirty) {
				alt[1] = " x-grid3-dirty-row";
			}
			rp.cols = colCount;
			if (this.getRowClass) {
				alt[2] = this.getRowClass(r, rowIndex, rp, ds);
			}
			rp.alt = alt.join(" ");
			rp.cells = cb.join("");
			buf[buf.length] = rt.apply(rp);
		}
		return buf.join("");
	}
})


/**
 * @ignore
 * Overload, store apploySort
 */
Ext.data.Store.prototype.applySort = function() {
    if (this.sortInfo && !this.remoteSort) {
        var s = this.sortInfo, f = s.field;
        var st = this.fields.get(f).sortType;
        var fn = function(r1, r2) {
            var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
            if (typeof(v1) == "string") {
                return v1.localeCompare(v2);
            }
            return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
        };
        this.data.sort(s.direction, fn);
        if(this.snapshot && this.snapshot != this.data) {
            this.snapshot.sort(s.direction, fn);
        }
    }
};

/**
 * @ignore
 * grideditor render for monthfield
 */
Wonders.grid.monthFieldRender = function(value) {
	if(typeof value == "undefined"){
			return "";
	}
	if(typeof value == "string"){
			return value; 
	}
	return value.format("Ym"); 
}

/**
* @ignore
* 允许表格selectMode=cell模式下复制cell内容
* Wonders.utils.copyCellContent
* param gridId/grid,表格或其ID
*/
Wonders.grid.copyCellContent = function(g) {
	var grid=g;
	if(typeof(grid)=="string"){
		grid=Ext.getCmp(grid);
	}
	grid.on('cellclick', function(g, row, col,e){
		if(window.getSelection){
			var st=window.getSelection();
			if(st.rangeCount>0){//FireFox
				var rng=st.getRangeAt(0);
				rng.selectNodeContents(e.target);
			}else{//Chorme
				var rng=document.createRange();
				rng.selectNodeContents(e.target);
				st.addRange(rng);
			}
		}else{//IE
			if(document.body.createTextRange){
				var rng=document.body.createTextRange();
				rng.moveToElementText(e.target);
				rng.select();
			}
		}
	});
}

function checkExcelAll(obj,gridId){
    var id="";
    var grid = Ext.getCmp(gridId);
    var colModel=grid.getColumnModel();
    var count=colModel.getColumnCount();
    if(obj.checked == true){
        for(var i = 0; i < count; i++){
        	if(colModel.config[i].exportColumn == true){
        		id=colModel.getColumnId(i);
               document.getElementById('g_c_'+id).checked = true;
        	}
        }
    }else {
        for(var i = 0; i < count; i++){
        	if(colModel.config[i].exportColumn == true){
        		id=colModel.getColumnId(i);
               document.getElementById('g_c_'+id).checked = false;
        	}
        }
    }
}
